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

Lukas Tönne noreply at git.blender.org
Mon Apr 20 14:22:48 CEST 2015


Commit: afb947c00c134671c8203bf1a69c46aea92230ec
Author: Lukas Tönne
Date:   Wed Nov 26 20:11:38 2014 +0100
Branches: strand_editmode
https://developer.blender.org/rBafb947c00c134671c8203bf1a69c46aea92230ec

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).

Conflicts:
	source/blender/blenkernel/intern/customdata.c
	source/blender/makesdna/DNA_customdata_types.h

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

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 0ac7fe0..bf1ca41 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -92,6 +92,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 add6bb0..baf6639 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -55,6 +55,7 @@
 
 #include "BKE_customdata.h"
 #include "BKE_customdata_file.h"
+#include "BKE_edithair.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
 #include "BKE_mesh_mapping.h"
@@ -1312,6 +1313,10 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
 	{sizeof(short[4][3]), "", 0, NULL, NULL, NULL, NULL, layerSwap_flnor, NULL},
 	/* 41: CD_CUSTOMLOOPNORMAL */
 	{sizeof(short[2]), "vec2s", 1, NULL, NULL, NULL, NULL, NULL, 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