[Bf-blender-cvs] [e490bfc] hair_immediate_fixes: Constrain hair root vertices to their mesh location after applying tools.

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


Commit: e490bfc37e233b89c51ffdbe9811fe28a45081e7
Author: Lukas Tönne
Date:   Tue Dec 2 17:26:25 2014 +0100
Branches: hair_immediate_fixes
https://developer.blender.org/rBe490bfc37e233b89c51ffdbe9811fe28a45081e7

Constrain hair root vertices to their mesh location after applying tools.

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

M	source/blender/blenkernel/BKE_edithair.h
M	source/blender/blenkernel/intern/edithair.c
M	source/blender/bmesh/intern/bmesh_interp.c
M	source/blender/bmesh/intern/bmesh_interp.h
M	source/blender/bmesh/intern/bmesh_strands_conv.c
M	source/blender/editors/hair/hair_edit.c
M	source/blender/editors/hair/hair_stroke.c

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

diff --git a/source/blender/blenkernel/BKE_edithair.h b/source/blender/blenkernel/BKE_edithair.h
index 3c78021..5653047 100644
--- a/source/blender/blenkernel/BKE_edithair.h
+++ b/source/blender/blenkernel/BKE_edithair.h
@@ -40,6 +40,7 @@
 #include "bmesh.h"
 
 struct BMesh;
+struct DerivedMesh;
 struct Object;
 
 typedef struct BMEditStrands {
@@ -54,12 +55,13 @@ typedef struct BMEditStrands {
 	
 	/* Object this editmesh came from (if it came from one) */
 	struct Object *ob;
+	struct DerivedMesh *root_dm;
 	
 	unsigned int vertex_glbuf;
 	unsigned int elem_glbuf;
 } BMEditStrands;
 
-struct BMEditStrands *BKE_editstrands_create(struct BMesh *bm);
+struct BMEditStrands *BKE_editstrands_create(struct BMesh *bm, struct DerivedMesh *root_dm);
 struct BMEditStrands *BKE_editstrands_copy(struct BMEditStrands *es);
 struct BMEditStrands *BKE_editstrands_from_object(struct Object *ob);
 void BKE_editstrands_update_linked_customdata(struct BMEditStrands *es);
diff --git a/source/blender/blenkernel/intern/edithair.c b/source/blender/blenkernel/intern/edithair.c
index 6beb5f5..e1064d9 100644
--- a/source/blender/blenkernel/intern/edithair.c
+++ b/source/blender/blenkernel/intern/edithair.c
@@ -41,17 +41,20 @@
 
 #include "BKE_bvhutils.h"
 #include "BKE_customdata.h"
+#include "BKE_cdderivedmesh.h"
 #include "BKE_edithair.h"
 #include "BKE_DerivedMesh.h"
+#include "BKE_mesh_sample.h"
 #include "BKE_particle.h"
 
 #include "intern/bmesh_strands_conv.h"
 
-BMEditStrands *BKE_editstrands_create(BMesh *bm)
+BMEditStrands *BKE_editstrands_create(BMesh *bm, DerivedMesh *root_dm)
 {
 	BMEditStrands *es = MEM_callocN(sizeof(BMEditStrands), __func__);
 	
 	es->bm = bm;
+	es->root_dm = CDDM_copy(root_dm);
 	
 	return es;
 }
@@ -62,6 +65,7 @@ BMEditStrands *BKE_editstrands_copy(BMEditStrands *es)
 	*es_copy = *es;
 	
 	es_copy->bm = BM_mesh_copy(es->bm);
+	es_copy->root_dm = CDDM_copy(es->root_dm);
 	
 	return es_copy;
 }
@@ -91,6 +95,8 @@ void BKE_editstrands_free(BMEditStrands *es)
 {
 	if (es->bm)
 		BM_mesh_free(es->bm);
+	if (es->root_dm)
+		es->root_dm->release(es->root_dm);
 }
 
 /* === constraints === */
@@ -112,19 +118,36 @@ void BKE_editstrands_calc_segment_lengths(BMesh *bm)
 	}
 }
 
-void BKE_editstrands_solve_constraints(BMEditStrands *es)
+static void editstrands_apply_root_locations(BMesh *bm, DerivedMesh *root_dm)
 {
-	/* XXX Simplistic implementation from particles:
-	 * adjust segment lengths starting from the root.
-	 * This should be replaced by a more advanced method using a least-squares
-	 * error metric with length and root location constraints
-	 */
+	BMVert *root;
+	BMIter iter;
 	
-	BMesh *bm = es->bm;
+	if (!root_dm)
+		return;
+	
+	BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) {
+		MSurfaceSample root_sample;
+		float loc[3], nor[3];
+		
+		BM_elem_meshsample_data_named_get(&bm->vdata, root, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, &root_sample);
+		if (BKE_mesh_sample_eval(root_dm, &root_sample, loc, nor)) {
+			copy_v3_v3(root->co, loc);
+		}
+	}
+}
+
+static void editstrands_solve_segment_lengths(BMesh *bm)
+{
 	BMVert *root, *v, *vprev;
 	BMIter iter, iter_strand;
 	int k;
 	
+	/* XXX Simplistic implementation from particles:
+	 * adjust segment lengths starting from the root.
+	 * This should be replaced by a more advanced method using a least-squares
+	 * error metric with length and root location constraints
+	 */
 	BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) {
 		BM_ITER_STRANDS_ELEM_INDEX(v, &iter_strand, root, BM_VERTS_OF_STRAND, k) {
 			if (k > 0) {
@@ -142,6 +165,12 @@ void BKE_editstrands_solve_constraints(BMEditStrands *es)
 	}
 }
 
+void BKE_editstrands_solve_constraints(BMEditStrands *es)
+{
+	editstrands_apply_root_locations(es->bm, es->root_dm);
+	editstrands_solve_segment_lengths(es->bm);
+}
+
 
 /* === particle conversion === */
 
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index f93675f..98444de 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -905,3 +905,19 @@ void BM_elem_float_data_named_set(CustomData *cd, void *element, int type, const
 	float *f = CustomData_bmesh_get_named(cd, ((BMHeader *)element)->data, type, name);
 	if (f) *f = val;
 }
+
+void BM_elem_meshsample_data_named_get(CustomData *cd, void *element, int type, const char *name, MSurfaceSample *val)
+{
+	const MSurfaceSample *s = CustomData_bmesh_get_named(cd, ((BMHeader *)element)->data, type, name);
+	if (s)
+		memcpy(val, s, sizeof(MSurfaceSample));
+	else
+		memset(val, 0, sizeof(MSurfaceSample));
+}
+
+void BM_elem_meshsample_data_named_set(CustomData *cd, void *element, int type, const char *name, const MSurfaceSample *val)
+{
+	MSurfaceSample *s = CustomData_bmesh_get_named(cd, ((BMHeader *)element)->data, type, name);
+	if (s)
+		memcpy(s, val, sizeof(MSurfaceSample));
+}
diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h
index 0315702..0930295 100644
--- a/source/blender/bmesh/intern/bmesh_interp.h
+++ b/source/blender/bmesh/intern/bmesh_interp.h
@@ -27,6 +27,8 @@
  *  \ingroup bmesh
  */
 
+struct MSurfaceSample;
+
 void  BM_loop_interp_multires(BMesh *bm, BMLoop *target, BMFace *source);
 void  BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source);
 
@@ -43,6 +45,8 @@ float BM_elem_float_data_get(CustomData *cd, void *element, int type);
 void  BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val);
 float BM_elem_float_data_named_get(CustomData *cd, void *element, int type, const char *name);
 void BM_elem_float_data_named_set(CustomData *cd, void *element, int type, const char *name, const float val);
+void BM_elem_meshsample_data_named_get(CustomData *cd, void *element, int type, const char *name, struct MSurfaceSample *val);
+void BM_elem_meshsample_data_named_set(CustomData *cd, void *element, int type, const char *name, const struct MSurfaceSample *val);
 
 void BM_face_interp_from_face_ex(BMesh *bm, BMFace *target, BMFace *source, const bool do_vertex,
                                  void **blocks, void **blocks_v, float (*cos_2d)[2], float axis_mat[3][3]);
diff --git a/source/blender/bmesh/intern/bmesh_strands_conv.c b/source/blender/bmesh/intern/bmesh_strands_conv.c
index 0dfb89c..786b35b 100644
--- a/source/blender/bmesh/intern/bmesh_strands_conv.c
+++ b/source/blender/bmesh/intern/bmesh_strands_conv.c
@@ -50,22 +50,6 @@ const char *CD_HAIR_MASS = "HAIR_MASS";
 const char *CD_HAIR_WEIGHT = "HAIR_WEIGHT";
 const char *CD_HAIR_ROOT_LOCATION = "HAIR_ROOT_LOCATION";
 
-static void BM_elem_msample_data_named_get(CustomData *cd, void *element, int type, const char *name, MSurfaceSample *val)
-{
-	const MSurfaceSample *s = CustomData_bmesh_get_named(cd, ((BMHeader *)element)->data, type, name);
-	if (s)
-		memcpy(val, s, sizeof(MSurfaceSample));
-	else
-		memset(val, 0, sizeof(MSurfaceSample));
-}
-
-static void BM_elem_msample_data_named_set(CustomData *cd, void *element, int type, const char *name, const MSurfaceSample *val)
-{
-	MSurfaceSample *s = CustomData_bmesh_get_named(cd, ((BMHeader *)element)->data, type, name);
-	if (s)
-		memcpy(s, val, sizeof(MSurfaceSample));
-}
-
 /* ------------------------------------------------------------------------- */
 
 int BM_strands_count_psys_keys(ParticleSystem *psys)
@@ -229,7 +213,7 @@ static void bm_make_particles(BMesh *bm, Object *ob, ParticleSystem *psys, struc
 			if (k == 0) {
 				MSurfaceSample root_loc;
 				if (BKE_mesh_sample_from_particle(&root_loc, psys, emitter_dm, pa)) {
-					BM_elem_msample_data_named_set(&bm->vdata, v, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, &root_loc);
+					BM_elem_meshsample_data_named_set(&bm->vdata, v, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, &root_loc);
 				}
 			}
 			
@@ -478,7 +462,7 @@ static void make_particle_hair(BMesh *bm, BMVert *root, Object *ob, ParticleSyst
 		/* root */
 		if (k == 0) {
 			MSurfaceSample root_loc;
-			BM_elem_msample_data_named_get(&bm->vdata, v, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, &root_loc);
+			BM_elem_meshsample_data_named_get(&bm->vdata, v, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, &root_loc);
 			if (!BKE_mesh_sample_to_particle(&root_loc, psys, emitter_dm, emitter_bvhtree, pa)) {
 				pa->num = 0;
 				pa->num_dmcache = DMCACHE_NOTFOUND;
diff --git a/source/blender/editors/hair/hair_edit.c b/source/blender/editors/hair/hair_edit.c
index 90884f5..6b3bff3 100644
--- a/source/blender/editors/hair/hair_edit.c
+++ b/source/blender/editors/hair/hair_edit.c
@@ -43,8 +43,10 @@
 #include "DNA_screen_types.h"
 
 #include "BKE_brush.h"
+#include "BKE_cdderivedmesh.h"
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
 #include "BKE_edithair.h"
 #include "BKE_paint.h"
 #include "BKE_particle.h"
@@ -73,13 +75,22 @@ static bool has_hair_data(Object *ob)
 	return false;
 }
 
-static bool init_hair_edit(Object *ob)
+static bool init_hair_edit(Scene *scene, Object *ob)
 {
 	ParticleSystem *psys = psys_get_current(ob);
-	if (psys->part->type == PART_HAIR) {
+	BMesh *bm;
+	DerivedMesh *dm;
+	
+	if (psys && psys->part->type == PART_HAIR) {
 		if (!psys->hairedit) {
-			BMesh *bm = BKE_particles_to_bmesh(ob, psys);
-			psys->hairedit = BKE_editstrands_create(bm);
+			bm = BKE_particles_to_bmesh(ob, psys);
+			
+			if (ob->type == OB_MESH || ob->derivedFinal)
+				dm = ob->derivedFinal ? ob->derivedFinal : mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+			else
+				dm = NULL;
+			
+			psys->hairedit = BKE_editstrands_create(bm, dm);
 		}
 		return true;
 	}
@@ -146,6 +157,7 @@ int hair_edit_toggle_poll(bContext *C)
 
 static int hair_edit_toggle_exec(bContext *C, wmOperator *op)
 {
+	Scene *scene = CTX_data_scene(C);
 	Object *ob = CTX_data_active_object(C);
 	const int mode_flag = OB_MODE_HAIR_EDIT;
 	const bool is_mode_set = (ob->mode & mode_flag) != 0;
@@ -157,7 +169,7 @@ static int hair_edit_toggle_exec(bContext *C, wmOperator *op)
 	}
 
 	if (!is_mode_set) {
-		init_hair_edit(ob);
+		init_hair_edit(scene, ob);
 		ob->mode |= mode_flag;
 		
 //		toggle_particle_cursor(C, 1);
diff --git a/source/blender/editors/hair/hair_stroke.c b/source/blender/editors/hai

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list