[Bf-blender-cvs] [8545853] hair_immediate_fixes: Switched the hair edit data to a bmesh-like structure for consistency.

Lukas Tönne noreply at git.blender.org
Sat Dec 27 11:31:46 CET 2014


Commit: 854585306e8829580e37f29e2dfed0f6ab7e01b2
Author: Lukas Tönne
Date:   Wed Nov 26 20:11:38 2014 +0100
Branches: hair_immediate_fixes
https://developer.blender.org/rB854585306e8829580e37f29e2dfed0f6ab7e01b2

Switched the hair edit data to a bmesh-like structure for consistency.

This means using mempools to store curve and vertex data, which allows
arbitrary addition and removal of data more easily. Also this includes
an iterator system similar to bmesh iterators (although the simpler
topology makes it a lot less complex).

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

M	source/blender/blenkernel/BKE_edithair.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/customdata.c
M	source/blender/blenkernel/intern/edithair.c
A	source/blender/blenkernel/intern/edithair_inline.h
M	source/blender/blenkernel/intern/edithair_particles.c
M	source/blender/bmesh/intern/bmesh_iterators_inline.h
M	source/blender/editors/hair/hair_ops.c
M	source/blender/makesdna/DNA_customdata_types.h

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

diff --git a/source/blender/blenkernel/BKE_edithair.h b/source/blender/blenkernel/BKE_edithair.h
index 9e265e6..4f28aa9 100644
--- a/source/blender/blenkernel/BKE_edithair.h
+++ b/source/blender/blenkernel/BKE_edithair.h
@@ -32,35 +32,92 @@
  *  \ingroup bke
  */
 
+#include "BLI_utildefines.h"
+
 #include "DNA_customdata_types.h"
 
 /* hair curve */
 typedef struct HairEditCurve {
-	int start;          /* first vertex index */
-	int numverts;       /* number of vertices in the curve */
+	void *data;
+	
+	struct HairEditVertex *v;
 } HairEditCurve;
 
 typedef struct HairEditVertex {
+	struct HairEditVertex *next, *prev; /* next/prev verts on the strand */
+	
+	void *data;
+	
 	float co[3];
 } HairEditVertex;
 
 typedef struct HairEditData {
-	HairEditCurve *curves;
-	HairEditVertex *verts;
+	int totcurves, totverts;
 	
-	int totcurves, alloc_curves;
-	int totverts, alloc_verts;
+	/* element pools */
+	struct BLI_mempool *cpool, *vpool;
 	
-	CustomData hdata;   /* curve data */
-	CustomData vdata;   /* vertex data */
+	CustomData cdata, vdata;
 } HairEditData;
 
+/* ==== Iterators ==== */
+
+/* these iterate over all elements of a specific
+ * type in the mesh.
+ *
+ * be sure to keep 'bm_iter_itype_htype_map' in sync with any changes
+ */
+typedef enum HairEditIterType {
+	HAIREDIT_CURVES_OF_MESH = 1,
+	HAIREDIT_VERTS_OF_MESH = 2,
+	HAIREDIT_VERTS_OF_CURVE = 3,
+} HairEditIterType;
+
+#define HAIREDIT_ITYPE_MAX 4
+
+#define HAIREDIT_ITER(ele, iter, data, itype) \
+	for (ele = HairEdit_iter_new(iter, data, itype, NULL); ele; ele = HairEdit_iter_step(iter))
+
+#define HAIREDIT_ITER_INDEX(ele, iter, data, itype, indexvar) \
+	for (ele = HairEdit_iter_new(iter, data, itype, NULL), indexvar = 0; ele; ele = HairEdit_iter_step(iter), (indexvar)++)
+
+/* a version of HAIREDIT_ITER which keeps the next item in storage
+ * so we can delete the current item */
+#ifdef DEBUG
+#  define HAIREDIT_ITER_MUTABLE(ele, ele_next, iter, data, itype) \
+	for (ele = HairEdit_iter_new(iter, data, itype, NULL); \
+	ele ? ((void)((iter)->count = HairEdit_iter_mesh_count(itype, data)), \
+	       (void)(ele_next = HairEdit_iter_step(iter)), 1) : 0; \
+	ele = ele_next)
+#else
+#  define HAIREDIT_ITER_MUTABLE(ele, ele_next, iter, data, itype) \
+	for (ele = HairEdit_iter_new(iter, data, itype, NULL); ele ? ((ele_next = HairEdit_iter_step(iter)), 1) : 0; ele = ele_next)
+#endif
+
+
+#define HAIREDIT_ITER_ELEM(ele, iter, data, itype) \
+	for (ele = HairEdit_iter_new(iter, NULL, itype, data); ele; ele = HairEdit_iter_step(iter))
+
+#define HAIREDIT_ITER_ELEM_INDEX(ele, iter, data, itype, indexvar) \
+	for (ele = HairEdit_iter_new(iter, NULL, itype, data), indexvar = 0; ele; ele = HairEdit_iter_step(iter), (indexvar)++)
+
+#include "intern/edithair_inline.h"
+
+/* =================== */
+
 struct HairEditData *BKE_edithair_create(void);
-struct HairEditData *BKE_edithair_copy(struct HairEditData *hedit);
+
+void BKE_edithair_data_free(struct HairEditData *hedit);
 void BKE_edithair_free(struct HairEditData *hedit);
 
 void BKE_edithair_clear(struct HairEditData *hedit);
-void BKE_edithair_reserve(struct HairEditData *hedit, int alloc_curves, int alloc_verts, bool shrink);
+
+void BKE_edithair_get_min_max(struct HairEditData *hedit, float r_min[3], float r_max[3]);
+
+struct HairEditCurve *BKE_edithair_curve_create(struct HairEditData *hedit, struct HairEditCurve *example);
+
+int BKE_edithair_curve_vertex_count(struct HairEditData *hedit, struct HairEditCurve *c);
+struct HairEditVertex *BKE_edithair_curve_extend(struct HairEditData *hedit, struct HairEditCurve *c, struct HairEditVertex *example, int num);
 
 /* === particle conversion === */
 
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index aae9889..2bdb1c6 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -91,6 +91,7 @@ set(SRC
 	intern/displist.c
 	intern/dynamicpaint.c
 	intern/editderivedmesh.c
+	intern/edithair_inline.h
 	intern/edithair.c
 	intern/edithair_particles.c
 	intern/editmesh.c
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 0343529..6aeb5c1 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -54,6 +54,7 @@
 
 #include "BKE_customdata.h"
 #include "BKE_customdata_file.h"
+#include "BKE_edithair.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
 #include "BKE_multires.h"
@@ -1218,6 +1219,10 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
 	{sizeof(short[4][3]), "", 0, NULL, NULL, NULL, NULL, layerSwap_flnor, NULL},
 	/* 41: CD_MASK_FACEMAP */
 	{sizeof(int), "", 1, NULL, NULL, NULL, NULL, NULL, layerDefault_fmap, NULL},
+	/* 42: CD_HAIR_CURVE */
+	{sizeof(HairEditCurve), "HairEditCurve", 1, NULL, NULL, NULL, NULL, NULL, NULL},
+	/* 43: CD_HAIR_VERT */
+	{sizeof(HairEditVertex), "HairEditVertex", 1, NULL, NULL, NULL, NULL, NULL, NULL},
 };
 
 /* note, numbers are from trunk and need updating for bmesh */
diff --git a/source/blender/blenkernel/intern/edithair.c b/source/blender/blenkernel/intern/edithair.c
index ec229b9..af0ea4e 100644
--- a/source/blender/blenkernel/intern/edithair.c
+++ b/source/blender/blenkernel/intern/edithair.c
@@ -32,82 +32,226 @@
 #include "MEM_guardedalloc.h"
 
 #include "BLI_math.h"
+#include "BLI_mempool.h"
 
+#include "DNA_customdata_types.h"
+
+#include "BKE_customdata.h"
 #include "BKE_edithair.h"
 
+static const int chunksize_default_totcurve = 512;
+static const int allocsize_default_totcurve = 512;
+
+static const int chunksize_default_totvert = 1024;
+static const int allocsize_default_totvert = 1024;
+
+static void edithair_mempool_init(HairEditData *hedit)
+{
+	hedit->cpool = BLI_mempool_create(sizeof(HairEditCurve), allocsize_default_totcurve,
+	                                  chunksize_default_totcurve, BLI_MEMPOOL_ALLOW_ITER);
+	hedit->vpool = BLI_mempool_create(sizeof(HairEditVertex), allocsize_default_totvert,
+	                                  chunksize_default_totvert, BLI_MEMPOOL_ALLOW_ITER);
+}
+
 HairEditData *BKE_edithair_create(void)
 {
 	HairEditData *hedit = MEM_callocN(sizeof(HairEditData), "hair edit data");
+	
+	edithair_mempool_init(hedit);
+	
+	CustomData_reset(&hedit->cdata);
+	CustomData_reset(&hedit->vdata);
+	
 	return hedit;
 }
 
-HairEditData *BKE_edithair_copy(HairEditData *hedit)
+void BKE_edithair_data_free(HairEditData *hedit)
 {
-	HairEditData *thedit = MEM_dupallocN(hedit);
-	
-	if (hedit->curves) {
-		thedit->curves = MEM_dupallocN(hedit->curves);
+	if (CustomData_bmesh_has_free(&(hedit->cdata))) {
+		HairEditCurve *curve;
+		HairEditIter iter;
+		HAIREDIT_ITER(curve, &iter, hedit, HAIREDIT_CURVES_OF_MESH) {
+			CustomData_bmesh_free_block(&hedit->cdata, &curve->data);
+		}
 	}
 	
-	if (hedit->verts) {
-		thedit->verts = MEM_dupallocN(hedit->verts);
+	if (CustomData_bmesh_has_free(&(hedit->vdata))) {
+		HairEditVertex *vert;
+		HairEditIter iter;
+		HAIREDIT_ITER(vert, &iter, hedit, HAIREDIT_VERTS_OF_MESH) {
+			CustomData_bmesh_free_block(&hedit->vdata, &vert->data);
+		}
 	}
 	
-	return thedit;
+	/* Free custom data pools, This should probably go in CustomData_free? */
+	if (hedit->cdata.totlayer) BLI_mempool_destroy(hedit->cdata.pool);
+	if (hedit->vdata.totlayer) BLI_mempool_destroy(hedit->vdata.pool);
+	
+	/* free custom data */
+	CustomData_free(&hedit->cdata, 0);
+	CustomData_free(&hedit->vdata, 0);
+
+	/* destroy element pools */
+	BLI_mempool_destroy(hedit->cpool);
+	BLI_mempool_destroy(hedit->vpool);
+}
+
+void BKE_edithair_clear(HairEditData *hedit)
+{
+	/* free old data */
+	BKE_edithair_data_free(hedit);
+	memset(hedit, 0, sizeof(HairEditData));
+
+	/* allocate the memory pools for the hair elements */
+	edithair_mempool_init(hedit);
+
+	CustomData_reset(&hedit->cdata);
+	CustomData_reset(&hedit->vdata);
 }
 
 void BKE_edithair_free(HairEditData *hedit)
 {
-	if (hedit->curves) {
-		MEM_freeN(hedit->curves);
-	}
-	
-	if (hedit->verts) {
-		MEM_freeN(hedit->verts);
-	}
+	BKE_edithair_data_free(hedit);
 	
 	MEM_freeN(hedit);
 }
 
-void BKE_edithair_clear(HairEditData *hedit)
+void BKE_edithair_get_min_max(HairEditData *hedit, float r_min[3], float r_max[3])
 {
-	if (hedit->curves) {
-		MEM_freeN(hedit->curves);
-		hedit->curves = NULL;
+	if (hedit->totverts) {
+		HairEditVertex *vert;
+		HairEditIter iter;
+		
+		INIT_MINMAX(r_min, r_max);
+		
+		HAIREDIT_ITER(vert, &iter, hedit, HAIREDIT_VERTS_OF_MESH) {
+			minmax_v3v3_v3(r_min, r_max, vert->co);
+		}
 	}
-	hedit->totcurves = 0;
-	hedit->alloc_curves = 0;
-	
-	if (hedit->verts) {
-		MEM_freeN(hedit->verts);
-		hedit->verts = NULL;
+	else {
+		zero_v3(r_min);
+		zero_v3(r_max);
+	}
+}
+
+HairEditCurve *BKE_edithair_curve_create(HairEditData *hedit, HairEditCurve *example)
+{
+	HairEditCurve *c = NULL;
+
+	c = BLI_mempool_alloc(hedit->cpool);
+
+	/* --- assign all members --- */
+	c->data = NULL;
+
+	c->v = NULL;
+	/* --- done --- */
+
+	hedit->totcurves++;
+
+	if (example) {
+		CustomData_bmesh_copy_data(&hedit->cdata, &hedit->cdata, example->data, &c->data);
+	}
+	else {
+		CustomData_bmesh_set_default(&hedit->cdata, &c->data);
 	}
-	hedit->totverts = 0;
-	hedit->alloc_verts = 0;
+
+	return c;
 }
 
-void BKE_edithair_reserve(HairEditData *hedit, int alloc_curves, int alloc_verts, bool shrink)
+int BKE_edithair_curve_vertex_count(HairEditData *UNUSED(hedit), HairEditCurve *c)
 {
-	if (!hedit)
-		return;
+	const HairEditVertex *v;
+	int count = 0;
+	for (v = c->v; v; v = v->next) {
+		++count;
+	}
+	return count;
+}
+
+static HairEditVertex *edithair_vertex_create(HairEditData *hedit, HairEditVertex *example)
+{
+	HairEditVertex *v = NULL;
+
+	v = BLI_mempool_alloc(hedit->vpool);
+
+	/* --- assign all members --- */
+	v->data = NULL;
+
+	v->next = v->prev = NULL;
+	/* --- done --- */
+
+	hedit->totverts++;
+
+	if (example) {
+		CustomData_bmesh_copy_data(&hedit->vdata, &hedit->vdata, example->data, &v->data);
+	}
+	else {
+		CustomData_bmesh_set_default(&hedit->vdata, &v->data);
+	}
+
+	return v;
+}
+
+HairEditVertex *BKE_edithair_curve_extend(HairEditData *hedit, HairEditCurve *c, HairEditVertex *example, int num)
+{
+	HairEditVertex *v

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list