[Bf-blender-cvs] [3540ab88fd6] hair_object: Introduce curve and vertex customdata for hair.

Lukas Tönne noreply at git.blender.org
Sun Nov 18 12:31:31 CET 2018


Commit: 3540ab88fd6fb6c832894c020b9dde576d037afa
Author: Lukas Tönne
Date:   Sun Nov 18 10:51:54 2018 +0000
Branches: hair_object
https://developer.blender.org/rB3540ab88fd6fb6c832894c020b9dde576d037afa

Introduce curve and vertex customdata for hair.

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

M	source/blender/blenkernel/BKE_hair.h
M	source/blender/blenkernel/intern/hair.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/editors/hair/edithair.c
M	source/blender/makesdna/DNA_hair_types.h

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

diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index 82085152342..4e795cf601c 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -78,9 +78,10 @@ struct HairPattern *BKE_hair_pattern_new(void);
 void BKE_hair_pattern_free(struct HairPattern *pattern);
 struct HairPattern *BKE_hair_pattern_copy(const struct HairPattern *src_pattern, int flag);
 
+void BKE_hair_curve_data_init(struct HairCurveData *data);
 /* Does not free the data pointer itself! */
 void BKE_hair_curve_data_free(struct HairCurveData *data);
-void BKE_hair_curve_data_copy(struct HairCurveData *dst_data, const struct HairCurveData *src_data);
+void BKE_hair_curve_data_copy(struct HairCurveData *dst_data, const struct HairCurveData *src_data, int flag);
 
 /* === Scalp object === */
 
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 7816dc826c0..24d814fb5f3 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -71,6 +71,7 @@ void BKE_hair_init(HairSystem *hsys)
 
 	hsys->bb = BKE_boundbox_alloc_unit();
 
+	BKE_hair_curve_data_init(&hsys->curve_data);
 	hsys->pattern = BKE_hair_pattern_new();
 	hsys->draw_settings = BKE_hair_draw_settings_new();
 }
@@ -113,14 +114,22 @@ HairPattern *BKE_hair_pattern_copy(const HairPattern *src_pattern, int flag)
 	return dst_pattern;
 }
 
+void BKE_hair_curve_data_init(HairCurveData *data)
+{
+	CustomData_reset(&data->vdata);
+	CustomData_reset(&data->cdata);
+}
+
 /* Does not free the data pointer itself! */
 void BKE_hair_curve_data_free(HairCurveData *data)
 {
 	MEM_SAFE_FREE(data->curves);
 	MEM_SAFE_FREE(data->verts);
+	CustomData_free(&data->vdata, data->totverts);
+	CustomData_free(&data->cdata, data->totcurves);
 }
 
-void BKE_hair_curve_data_copy(HairCurveData *dst_data, const HairCurveData *src_data)
+void BKE_hair_curve_data_copy(HairCurveData *dst_data, const HairCurveData *src_data, int flag)
 {
 	if (src_data->curves)
 	{
@@ -132,6 +141,11 @@ void BKE_hair_curve_data_copy(HairCurveData *dst_data, const HairCurveData *src_
 	}
 	dst_data->totcurves = src_data->totcurves;
 	dst_data->totverts = src_data->totverts;
+
+	CustomDataMask mask = CD_MASK_EVERYTHING;
+	const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
+	CustomData_copy(&src_data->vdata, &dst_data->vdata, mask, alloc_type, dst_data->totverts);
+	CustomData_copy(&src_data->cdata, &dst_data->cdata, mask, alloc_type, dst_data->totcurves);
 }
 
 /** Free (or release) any data used by this hair system (does not free the hair system itself). */
@@ -175,7 +189,7 @@ void BKE_hair_copy_data(Main *UNUSED(bmain), HairSystem *hsys_dst, const HairSys
 	hsys_dst->edithair = NULL;
 
 	hsys_dst->pattern = BKE_hair_pattern_copy(hsys_src->pattern, flag);
-	BKE_hair_curve_data_copy(&hsys_dst->curve_data, &hsys_src->curve_data);
+	BKE_hair_curve_data_copy(&hsys_dst->curve_data, &hsys_src->curve_data, flag);
 
 	hsys_dst->mat = MEM_dupallocN(hsys_src->mat);
 
@@ -219,6 +233,8 @@ HairSystem *BKE_hair_new_nomain(int verts_len, int curves_len, int follicles_len
 
 	/* don't use CustomData_reset(...); because we dont want to touch customdata */
 	copy_vn_i(hsys->pattern->fdata.typemap, CD_NUMTYPES, -1);
+	copy_vn_i(hsys->curve_data.vdata.typemap, CD_NUMTYPES, -1);
+	copy_vn_i(hsys->curve_data.cdata.typemap, CD_NUMTYPES, -1);
 
 	hsys->curve_data.totverts = verts_len;
 	hsys->curve_data.totcurves = curves_len;
@@ -244,6 +260,8 @@ static HairSystem *hair_new_nomain_from_template_ex(
 	hsys_dst->pattern->num_follicles = follicles_len;
 
 	CustomData_copy(&hsys_src->pattern->fdata, &hsys_dst->pattern->fdata, mask, CD_CALLOC, follicles_len);
+	CustomData_copy(&hsys_src->curve_data.vdata, &hsys_dst->curve_data.vdata, mask, CD_CALLOC, verts_len);
+	CustomData_copy(&hsys_src->curve_data.cdata, &hsys_dst->curve_data.cdata, mask, CD_CALLOC, curves_len);
 
 	/* The destination hair system should at least have valid primary CD layers,
 	 * even in cases where the source hair system does not. */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 16eb2213375..86b5b04b776 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8424,6 +8424,8 @@ static void direct_link_hair(FileData *fd, HairSystem* hsys)
 
 	hsys->curve_data.curves = newdataadr(fd, hsys->curve_data.curves);
 	hsys->curve_data.verts = newdataadr(fd, hsys->curve_data.verts);
+	direct_link_customdata(fd, &hsys->curve_data.vdata, hsys->curve_data.totverts);
+	direct_link_customdata(fd, &hsys->curve_data.cdata, hsys->curve_data.totcurves);
 
 	hsys->mat = newdataadr(fd, hsys->mat);
 	test_pointer_array(fd, (void **)&hsys->mat);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index cccdde99606..07452b5f6c7 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2218,19 +2218,40 @@ static void write_mesh(WriteData *wd, Mesh *mesh)
 
 static void write_hair(WriteData *wd, HairSystem *hsys)
 {
-	writestruct(wd, ID_HA, HairSystem, 1, hsys);
+	if (hsys->id.us == 0 && !wd->use_memfile) {
+		return;
+	}
+
+	/* write a copy of the hair system, don't modify in place because it is
+	* not thread safe for threaded renders that are reading this */
+	HairSystem *old_hsys = hsys;
+	HairSystem copy_hsys = *hsys;
+	hsys = &copy_hsys;
+
+	/**
+	 * Those calls:
+	 *   - Reduce pattern->xdata.totlayer to number of layers to write.
+	 *   - Fill xlayers with those layers to be written.
+	 * Note that pattern->xdata is from now on invalid for Blender, but this is why the whole mesh is
+	 * a temp local copy!
+	 */
+	CustomDataLayer *vlayers = NULL, vlayers_buff[CD_TEMP_CHUNK_SIZE];
+	CustomDataLayer *clayers = NULL, clayers_buff[CD_TEMP_CHUNK_SIZE];
+	CustomDataLayer *flayers = NULL, flayers_buff[CD_TEMP_CHUNK_SIZE];
+	CustomData_file_write_prepare(&hsys->curve_data.vdata, &vlayers, vlayers_buff, ARRAY_SIZE(vlayers_buff));
+	CustomData_file_write_prepare(&hsys->curve_data.cdata, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff));
+
+	writestruct_at_address(wd, ID_HA, HairSystem, 1, old_hsys, hsys);
 	write_iddata(wd, &hsys->id);
 	if (hsys->adt) {
 		write_animdata(wd, hsys->adt);
 	}
 
-	if ( hsys->pattern )
+	if (hsys->pattern)
 	{
-		CustomDataLayer *flayers = NULL, flayers_buff[CD_TEMP_CHUNK_SIZE];
-
-		/* write a copy of the hair pattern, don't modify in place because it is
-		 * not thread safe for threaded renders that are reading this */
-		HairPattern cpattern = *hsys->pattern;
+		HairPattern *old_pattern = hsys->pattern;
+		HairPattern copy_pattern = *hsys->pattern;
+		HairPattern *pattern = &copy_pattern;
 
 		/**
 		 * Those calls:
@@ -2239,16 +2260,20 @@ static void write_hair(WriteData *wd, HairSystem *hsys)
 		 * Note that pattern->xdata is from now on invalid for Blender, but this is why the whole mesh is
 		 * a temp local copy!
 		 */
-		CustomData_file_write_prepare(&cpattern.fdata, &flayers, flayers_buff, ARRAY_SIZE(flayers_buff));
+		CustomData_file_write_prepare(&pattern->fdata, &flayers, flayers_buff, ARRAY_SIZE(flayers_buff));
 
-		writestruct_at_address(wd, DATA, HairPattern, 1, hsys->pattern, &cpattern);
-		writestruct(wd, DATA, HairFollicle, cpattern.num_follicles, cpattern.follicles);
+		writestruct_at_address(wd, DATA, HairPattern, 1, old_pattern, pattern);
+		writestruct(wd, DATA, HairFollicle, pattern->num_follicles, pattern->follicles);
 
-		write_customdata(wd, &hsys->id, cpattern.num_follicles, &cpattern.fdata, flayers, -1, 0);
+		write_customdata(wd, &hsys->id, pattern->num_follicles, &pattern->fdata, flayers, -1, 0);
+
+		pattern = old_pattern;
 	}
 
 	writestruct(wd, DATA, HairFiberCurve, hsys->curve_data.totcurves, hsys->curve_data.curves);
 	writestruct(wd, DATA, HairFiberVertex, hsys->curve_data.totverts, hsys->curve_data.verts);
+	write_customdata(wd, &hsys->id, hsys->curve_data.totverts, &hsys->curve_data.vdata, vlayers, -1, 0);
+	write_customdata(wd, &hsys->id, hsys->curve_data.totcurves, &hsys->curve_data.cdata, clayers, -1, 0);
 
 	if (hsys->draw_settings)
 	{
@@ -2256,6 +2281,16 @@ static void write_hair(WriteData *wd, HairSystem *hsys)
 	}
 
 	writedata(wd, DATA, sizeof(void *) * hsys->totcol, hsys->mat);
+
+	if (flayers && flayers != flayers_buff) {
+		MEM_freeN(flayers);
+	}
+	if (vlayers && vlayers != vlayers_buff) {
+		MEM_freeN(vlayers);
+	}
+	if (clayers && clayers != clayers_buff) {
+		MEM_freeN(clayers);
+	}
 }
 
 static void write_lattice(WriteData *wd, Lattice *lt)
diff --git a/source/blender/editors/hair/edithair.c b/source/blender/editors/hair/edithair.c
index 69482f6bbd2..9fa74c40bee 100644
--- a/source/blender/editors/hair/edithair.c
+++ b/source/blender/editors/hair/edithair.c
@@ -77,7 +77,7 @@ void ED_hair_edithair_make(Object *obedit)
 	hsys->edithair = MEM_callocN(sizeof(EditHair), "edithair");
 
 	hsys->edithair->pattern = BKE_hair_pattern_copy(hsys->pattern, 0);
-	BKE_hair_curve_data_copy(&hsys->edithair->curve_data, &hsys->curve_data);
+	BKE_hair_curve_data_copy(&hsys->edithair->curve_data, &hsys->curve_data, 0);
 }
 
 void ED_hair_edithair_load(Object *obedit)
@@ -87,7 +87,7 @@ void ED_hair_edithair_load(Object *obedit)
 	BKE_hair_pattern_free(hsys->pattern);
 	BKE_hair_curve_data_free(&hsys->curve_data);
 	hsys->pattern = BKE_hair_pattern_copy(hsys->edithair->pattern, 0);
-	BKE_hair_curve_data_copy(&hsys->curve_data, &hsys->edithair->curve_data);
+	BKE_hair_curve_data_copy(&hsys->curve_data, &hsys->edithair->curve_data, 0);
 }
 
 void ED_hair_edithair_free(Object *ob)
diff --git a/source/blender/makesdna/DNA_hair_types.h b/source/blender/makesdna/DNA_hair_types.h
index 02ddfbdd478..f4bd59883e0 100644
--- a/source/blender/makesdna/DNA_hair_types.h
+++ b/source/blender/makesdna/DNA_hair_types.h
@@ -90,6 +90,11 @@ typedef struct HairCurveData
 	int totcurves;
 	/* Number of curve vertices */
 	int totverts;
+
+	/* Per vertex custom data */
+	struct CustomData vdata;
+	/* Per curve custom data */
+	struct CustomData cdata;
 } HairCurveData;
 
 /* Editable hair da

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list