[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