[Bf-blender-cvs] [db145f8] strand_gpu: Support for the Strand data structure in the hair editmode.

Lukas Tönne noreply at git.blender.org
Wed Jul 6 12:13:18 CEST 2016


Commit: db145f8ec60e727df9e2f22c25d6aa5e35402509
Author: Lukas Tönne
Date:   Tue Jul 5 20:41:26 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rBdb145f8ec60e727df9e2f22c25d6aa5e35402509

Support for the Strand data structure in the hair editmode.

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

M	source/blender/blenkernel/BKE_editstrands.h
M	source/blender/blenkernel/BKE_strands.h
M	source/blender/blenkernel/intern/editstrands.c
M	source/blender/blenkernel/intern/strands.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/bmesh/intern/bmesh_strands_conv.c
M	source/blender/bmesh/intern/bmesh_strands_conv.h
M	source/blender/editors/hair/CMakeLists.txt
M	source/blender/editors/hair/hair_edit.c
M	source/blender/editors/hair/hair_intern.h
A	source/blender/editors/hair/hair_object_strands.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/modifiers/intern/MOD_strands.c

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

diff --git a/source/blender/blenkernel/BKE_editstrands.h b/source/blender/blenkernel/BKE_editstrands.h
index cc64191..9fb69ba 100644
--- a/source/blender/blenkernel/BKE_editstrands.h
+++ b/source/blender/blenkernel/BKE_editstrands.h
@@ -45,6 +45,7 @@ struct BMesh;
 struct DerivedMesh;
 struct Mesh;
 struct Object;
+struct Strands;
 
 typedef struct BMEditStrands {
 	BMEditMesh base;
@@ -84,7 +85,6 @@ void BKE_editstrands_solve_constraints(struct Object *ob, struct BMEditStrands *
 void BKE_editstrands_ensure(struct BMEditStrands *es);
 
 /* === particle conversion === */
-
 struct BMesh *BKE_editstrands_particles_to_bmesh(struct Object *ob, struct ParticleSystem *psys);
 void BKE_editstrands_particles_from_bmesh(struct Object *ob, struct ParticleSystem *psys);
 
@@ -92,4 +92,8 @@ void BKE_editstrands_particles_from_bmesh(struct Object *ob, struct ParticleSyst
 struct BMesh *BKE_editstrands_mesh_to_bmesh(struct Object *ob, struct Mesh *me);
 void BKE_editstrands_mesh_from_bmesh(struct Object *ob);
 
+/* === strands conversion === */
+struct BMesh *BKE_editstrands_strands_to_bmesh(struct Strands *strands, struct DerivedMesh *root_dm);
+void BKE_editstrands_strands_from_bmesh(struct Strands *strands, struct BMesh *bm, struct DerivedMesh *root_dm);
+
 #endif
diff --git a/source/blender/blenkernel/BKE_strands.h b/source/blender/blenkernel/BKE_strands.h
index d1d46e1..901d960 100644
--- a/source/blender/blenkernel/BKE_strands.h
+++ b/source/blender/blenkernel/BKE_strands.h
@@ -45,6 +45,9 @@ struct Strands *BKE_strands_new(void);
 struct Strands *BKE_strands_copy(struct Strands *strands);
 void BKE_strands_free(struct Strands *strands);
 
+bool BKE_strands_get_root_location(const struct StrandCurve *curve, struct DerivedMesh *root_dm, float loc[3]);
+bool BKE_strands_get_root_matrix(const struct StrandCurve *curve, struct DerivedMesh *root_dm, float mat[4][4]);
+
 /* ------------------------------------------------------------------------- */
 
 typedef struct StrandVertexData {
diff --git a/source/blender/blenkernel/intern/editstrands.c b/source/blender/blenkernel/intern/editstrands.c
index 23b17c7..f0d8ea6 100644
--- a/source/blender/blenkernel/intern/editstrands.c
+++ b/source/blender/blenkernel/intern/editstrands.c
@@ -51,6 +51,7 @@
 #include "BKE_mesh_sample.h"
 #include "BKE_object.h"
 #include "BKE_particle.h"
+#include "BKE_strands.h"
 
 #include "BPH_strands.h"
 
@@ -95,6 +96,17 @@ BMEditStrands *BKE_editstrands_from_object(Object *ob)
 			return psys->hairedit;
 	}
 	
+	{
+		ModifierData *md;
+		for (md = ob->modifiers.first; md; md = md->next) {
+			if (md->type == eModifierType_Strands) {
+				StrandsModifierData *smd = (StrandsModifierData *)md;
+				if (smd->edit)
+					return smd->edit;
+			}
+		}
+	}
+	
 	return NULL;
 }
 
@@ -262,3 +274,27 @@ void BKE_editstrands_mesh_from_bmesh(Object *ob)
 	 * avoid ending up with an invalid derived mesh then */
 	BKE_object_free_derived_caches(ob);
 }
+
+/* === strands conversion === */
+
+BMesh *BKE_editstrands_strands_to_bmesh(Strands *strands, DerivedMesh *root_dm)
+{
+	const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_STRANDS(strands);
+	BMesh *bm;
+
+	bm = BM_mesh_create(&allocsize,
+	                    &((struct BMeshCreateParams){.use_toolflags = false,}));
+
+	BM_bm_from_strands(bm, strands, root_dm, true, -1);
+	
+	editstrands_calc_segment_lengths(bm);
+
+	return bm;
+}
+
+void BKE_editstrands_strands_from_bmesh(Strands *strands, BMesh *bm, DerivedMesh *root_dm)
+{
+	if (bm) {
+		BM_bm_to_strands(bm, strands, root_dm);
+	}
+}
diff --git a/source/blender/blenkernel/intern/strands.c b/source/blender/blenkernel/intern/strands.c
index a4d6452..847bd5f 100644
--- a/source/blender/blenkernel/intern/strands.c
+++ b/source/blender/blenkernel/intern/strands.c
@@ -84,6 +84,34 @@ void BKE_strands_free(Strands *strands)
 	MEM_freeN(strands);
 }
 
+bool BKE_strands_get_root_location(const StrandCurve *curve, DerivedMesh *root_dm, float loc[3])
+{
+	float nor[3], tang[3];
+	if (BKE_mesh_sample_eval(root_dm, &curve->root, loc, nor, tang)) {
+		return true;
+	}
+	else {
+		zero_v3(loc);
+		return false;
+	}
+}
+
+bool BKE_strands_get_root_matrix(const StrandCurve *curve, DerivedMesh *root_dm, float mat[4][4])
+{
+	if (BKE_mesh_sample_eval(root_dm, &curve->root, mat[3], mat[2], mat[0])) {
+		cross_v3_v3v3(mat[1], mat[2], mat[0]);
+		mat[0][3] = 0.0f;
+		mat[1][3] = 0.0f;
+		mat[2][3] = 0.0f;
+		mat[3][3] = 1.0f;
+		return true;
+	}
+	else {
+		unit_m4(mat);
+		return false;
+	}
+}
+
 /* ------------------------------------------------------------------------- */
 
 StrandData *BKE_strand_data_calc(Strands *strands, DerivedMesh *scalp,
@@ -105,8 +133,7 @@ StrandData *BKE_strand_data_calc(Strands *strands, DerivedMesh *scalp,
 		curve->verts_begin = scurve->verts_begin;
 		curve->num_verts = scurve->num_verts;
 		
-		BKE_mesh_sample_eval(scalp, &scurve->root, curve->mat[3], curve->mat[2], curve->mat[0]);
-		cross_v3_v3v3(curve->mat[1], curve->mat[2], curve->mat[0]);
+		BKE_strands_get_root_matrix(scurve, scalp, curve->mat);
 		
 		int v;
 		StrandVertex *svert = strands->verts + scurve->verts_begin;
@@ -255,8 +282,7 @@ static void strands_calc_weights(const Strands *strands, struct DerivedMesh *sca
 		int c;
 		const StrandCurve *curve = strands->curves;
 		for (c = 0; c < strands->totcurves; ++c, ++curve) {
-			float nor[3], tang[3];
-			if (BKE_mesh_sample_eval(scalp, &curve->root, strandloc[c], nor, tang))
+			if (BKE_strands_get_root_location(curve, scalp, strandloc[c]))
 				BLI_kdtree_insert(tree, c, strandloc[c]);
 		}
 		BLI_kdtree_balance(tree);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 1a2f154..2d881e9 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5283,6 +5283,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
 				direct_link_strands(fd, smd->strands);
 			}
 			smd->roots = newdataadr(fd, smd->roots);
+			
+			smd->edit = NULL;
 		}
 	}
 }
diff --git a/source/blender/bmesh/intern/bmesh_strands_conv.c b/source/blender/bmesh/intern/bmesh_strands_conv.c
index d74ceac..e30765e 100644
--- a/source/blender/bmesh/intern/bmesh_strands_conv.c
+++ b/source/blender/bmesh/intern/bmesh_strands_conv.c
@@ -26,10 +26,11 @@
  * BM mesh conversion functions.
  */
 
+#include "DNA_key_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
 #include "DNA_particle_types.h"
-#include "DNA_key_types.h"
+#include "DNA_strand_types.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -41,6 +42,7 @@
 #include "BKE_main.h"
 #include "BKE_mesh_sample.h"
 #include "BKE_particle.h"
+#include "BKE_strands.h"
 
 #include "bmesh.h"
 #include "intern/bmesh_private.h" /* for element checking */
@@ -96,7 +98,448 @@ char BM_strands_cd_flag_from_bmesh(BMesh *UNUSED(bm))
 	return cd_flag;
 }
 
-/* particles */
+/***********/
+/* Strands */
+
+/* create vertex and edge data for BMesh based on strand curves */
+static void bm_make_strands(BMesh *bm, Strands *strands, struct DerivedMesh *root_dm,
+                            float (*keyco)[3], int cd_shape_keyindex_offset)
+{
+	int vindex, eindex;
+	BMVert *v = NULL, *v_prev;
+	BMEdge *e;
+	
+	vindex = 0;
+	eindex = 0;
+	StrandCurve *curve = strands->curves;
+	for (int i = 0; i < strands->totcurves; ++i, ++curve) {
+		float rootmat[4][4];
+		
+		/* strand vertices are in a local "root space", but edit data should be in object space */
+		BKE_strands_get_root_matrix(curve, root_dm, rootmat);
+		
+		StrandVertex *vert = strands->verts + curve->verts_begin;
+		for (int k = 0; k < curve->num_verts; ++k, ++vert) {
+			float co[3];
+			
+			copy_v3_v3(co, keyco ? keyco[vindex] : vert->co);
+			mul_m4_v3(rootmat, co);
+			
+			v_prev = v;
+			v = BM_vert_create(bm, co, NULL, BM_CREATE_SKIP_CD);
+			BM_elem_index_set(v, vindex); /* set_ok */
+			
+			/* transfer flag */
+//			v->head.hflag = BM_vert_flag_from_mflag(mvert->flag & ~SELECT);
+			
+			/* this is necessary for selection counts to work properly */
+//			if (hkey->editflag & SELECT) {
+//				BM_vert_select_set(bm, v, true);
+//			}
+			
+			/* Copy Custom Data */
+//			CustomData_to_bmesh_block(&me->vdata, &bm->vdata, vindex, &v->head.data, true);
+			CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
+			
+			/* root */
+			if (k == 0) {
+				BM_elem_meshsample_data_named_set(&bm->vdata, v, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, &curve->root);
+			}
+			
+#if 0
+			/* set shapekey data */
+			if (strands->key) {
+				/* set shape key original index */
+				if (cd_shape_keyindex_offset != -1) BM_ELEM_CD_SET_INT(v, cd_shape_keyindex_offset, vindex);
+				
+				for (block = strands->key->block.first, j = 0; block; block = block->next, j++) {
+					float *co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, j);
+					
+					if (co) {
+						copy_v3_v3(co, ((float *)block->data) + 3 * vindex);
+					}
+				}
+			}
+#else
+			UNUSED_VARS(cd_shape_keyindex_offset);
+#endif
+			
+			vindex += 1;
+			
+			if (k > 0) {
+				e = BM_edge_create(bm, v_prev, v, NULL, BM_CREATE_SKIP_CD);
+				BM_elem_index_set(e, eindex); /* set_ok; one less edge than vertices for each particle */
+				
+				/* transfer flags */
+//				e->head.hflag = BM_edge_flag_from_mflag(medge->flag & ~SELECT);
+				
+				/* this is necessary for selection counts to work properly */
+//				if (medge->flag & SELECT) {
+//					BM_edge_select_set(bm, e, true);
+//				}
+				
+				/* Copy Custom Data */
+//				CustomData_to_bmesh_block(&me->edata, &bm->edata, eindex, &e->head.data, true);
+				CustomData_bmesh_set_default(&bm->edata, &e->head.data);
+				
+				eindex += 1;
+			}
+			
+		} /* vertices */
+	
+	} /* curves */
+	
+	bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE); /* added in order, clear dirty flag */
+}
+
+/**
+ * \brief Strands -> BMesh
+ */
+void BM_bm_from_strands(BMesh *bm, Strands *strands, struct DerivedMesh *root_dm,
+                        const bool set_key, int act_key_nr)
+{
+	KeyBlock *actkey;
+	float (*keyco)[3] = NULL;
+	int totvert, totedge;
+	
+	int cd_shape_keyindex_offset;
+	
+	/* free custom data */
+	/* this isnt needed in most cases but do just incase */
+	CustomData_f

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list