Commit: 2db0330c713031e8536c16931f3cb864157117ad
Author: Lukas Tönne
Date:   Fri Dec 5 14:42:22 2014 +0100
Branches: hair_immediate_fixes
https://developer.blender.org/rB2db0330c713031e8536c16931f3cb864157117ad

Basic Add tool for creating new strands in hair edit mode.

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

M       source/blender/blenkernel/BKE_edithair.h
M       source/blender/blenkernel/BKE_mesh_sample.h
M       source/blender/blenkernel/intern/edithair.c
M       source/blender/blenkernel/intern/mesh_sample.c
M       source/blender/bmesh/intern/bmesh_strands.c
M       source/blender/bmesh/intern/bmesh_strands.h
M       source/blender/bmesh/intern/bmesh_strands_conv.c
M       source/blender/bmesh/intern/bmesh_strands_conv.h
M       source/blender/editors/hair/hair_edit.c
M       source/blender/editors/hair/hair_intern.h
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 070f8df..7d39ff6 100644
--- a/source/blender/blenkernel/BKE_edithair.h
+++ b/source/blender/blenkernel/BKE_edithair.h
@@ -54,11 +54,18 @@ typedef struct BMEditStrands {
        struct Object *ob;
        struct DerivedMesh *root_dm;
        
+       int flag;
+       
        unsigned int vertex_glbuf;
        unsigned int elem_glbuf;
        unsigned int dot_glbuf;
 } BMEditStrands;
 
+/* BMEditStrands->flag */
+typedef enum BMEditStrandsFlag {
+       BM_STRANDS_DIRTY_SEGLEN     = 1,
+} BMEditStrandsFlag;
+
 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);
@@ -67,9 +74,8 @@ void BKE_editstrands_free(struct BMEditStrands *es);
 
 /* === constraints === */
 
-void BKE_editstrands_calc_segment_lengths(struct BMesh *bm);
-
 void BKE_editstrands_solve_constraints(struct BMEditStrands *es);
+void BKE_editstrands_ensure(struct BMEditStrands *es);
 
 /* === particle conversion === */
 
diff --git a/source/blender/blenkernel/BKE_mesh_sample.h 
b/source/blender/blenkernel/BKE_mesh_sample.h
index e43b162..6b48955 100644
--- a/source/blender/blenkernel/BKE_mesh_sample.h
+++ b/source/blender/blenkernel/BKE_mesh_sample.h
@@ -33,7 +33,7 @@ struct MSurfaceSample;
 
 /* ==== Evaluate ==== */
 
-bool BKE_mesh_sample_eval(struct DerivedMesh *dm, const struct MSurfaceSample 
*sample, float loc[3], float nor[3]);
+bool BKE_mesh_sample_eval(struct DerivedMesh *dm, const struct MSurfaceSample 
*sample, float loc[3], float nor[3], float tang[3]);
 bool BKE_mesh_sample_shapekey(struct Key *key, struct KeyBlock *kb, const 
struct MSurfaceSample *sample, float loc[3]);
 
 
diff --git a/source/blender/blenkernel/intern/edithair.c 
b/source/blender/blenkernel/intern/edithair.c
index e1064d9..2da64f1 100644
--- a/source/blender/blenkernel/intern/edithair.c
+++ b/source/blender/blenkernel/intern/edithair.c
@@ -101,7 +101,7 @@ void BKE_editstrands_free(BMEditStrands *es)
 
 /* === constraints === */
 
-void BKE_editstrands_calc_segment_lengths(BMesh *bm)
+static void editstrands_calc_segment_lengths(BMesh *bm)
 {
        BMVert *root, *v, *vprev;
        BMIter iter, iter_strand;
@@ -128,10 +128,10 @@ static void editstrands_apply_root_locations(BMesh *bm, 
DerivedMesh *root_dm)
        
        BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) {
                MSurfaceSample root_sample;
-               float loc[3], nor[3];
+               float loc[3], nor[3], tang[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)) {
+               if (BKE_mesh_sample_eval(root_dm, &root_sample, loc, nor, 
tang)) {
                        copy_v3_v3(root->co, loc);
                }
        }
@@ -167,10 +167,23 @@ static void editstrands_solve_segment_lengths(BMesh *bm)
 
 void BKE_editstrands_solve_constraints(BMEditStrands *es)
 {
+       BKE_editstrands_ensure(es);
+       
        editstrands_apply_root_locations(es->bm, es->root_dm);
        editstrands_solve_segment_lengths(es->bm);
 }
 
+void BKE_editstrands_ensure(BMEditStrands *es)
+{
+       BM_strands_cd_flag_ensure(es->bm, 0);
+       
+       if (es->flag & BM_STRANDS_DIRTY_SEGLEN) {
+               editstrands_calc_segment_lengths(es->bm);
+               
+               es->flag &= ~BM_STRANDS_DIRTY_SEGLEN;
+       }
+}
+
 
 /* === particle conversion === */
 
@@ -188,7 +201,7 @@ BMesh *BKE_particles_to_bmesh(Object *ob, ParticleSystem 
*psys)
                
                BM_strands_bm_from_psys(bm, ob, psys, psmd->dm, true, 
psys->shapenr);
                
-               BKE_editstrands_calc_segment_lengths(bm);
+               editstrands_calc_segment_lengths(bm);
        }
 
        return bm;
diff --git a/source/blender/blenkernel/intern/mesh_sample.c 
b/source/blender/blenkernel/intern/mesh_sample.c
index b4c5903..c36d2add 100644
--- a/source/blender/blenkernel/intern/mesh_sample.c
+++ b/source/blender/blenkernel/intern/mesh_sample.c
@@ -43,15 +43,15 @@
 
 /* ==== Evaluate ==== */
 
-bool BKE_mesh_sample_eval(DerivedMesh *dm, const MSurfaceSample *sample, float 
loc[3], float nor[3])
+bool BKE_mesh_sample_eval(DerivedMesh *dm, const MSurfaceSample *sample, float 
loc[3], float nor[3], float tang[3])
 {
        MVert *mverts = dm->getVertArray(dm);
        unsigned int totverts = (unsigned int)dm->getNumVerts(dm);
        MVert *v1, *v2, *v3;
-       float vnor[3];
        
        zero_v3(loc);
        zero_v3(nor);
+       zero_v3(tang);
        
        if (sample->orig_verts[0] >= totverts ||
            sample->orig_verts[1] >= totverts ||
@@ -62,18 +62,39 @@ bool BKE_mesh_sample_eval(DerivedMesh *dm, const 
MSurfaceSample *sample, float l
        v2 = &mverts[sample->orig_verts[1]];
        v3 = &mverts[sample->orig_verts[2]];
        
-       madd_v3_v3fl(loc, v1->co, sample->orig_weights[0]);
-       madd_v3_v3fl(loc, v2->co, sample->orig_weights[1]);
-       madd_v3_v3fl(loc, v3->co, sample->orig_weights[2]);
+       { /* location */
+               madd_v3_v3fl(loc, v1->co, sample->orig_weights[0]);
+               madd_v3_v3fl(loc, v2->co, sample->orig_weights[1]);
+               madd_v3_v3fl(loc, v3->co, sample->orig_weights[2]);
+       }
        
-       normal_short_to_float_v3(vnor, v1->no);
-       madd_v3_v3fl(nor, vnor, sample->orig_weights[0]);
-       normal_short_to_float_v3(vnor, v2->no);
-       madd_v3_v3fl(nor, vnor, sample->orig_weights[1]);
-       normal_short_to_float_v3(vnor, v3->no);
-       madd_v3_v3fl(nor, vnor, sample->orig_weights[2]);
+       { /* normal */
+               float vnor[3];
+               
+               normal_short_to_float_v3(vnor, v1->no);
+               madd_v3_v3fl(nor, vnor, sample->orig_weights[0]);
+               normal_short_to_float_v3(vnor, v2->no);
+               madd_v3_v3fl(nor, vnor, sample->orig_weights[1]);
+               normal_short_to_float_v3(vnor, v3->no);
+               madd_v3_v3fl(nor, vnor, sample->orig_weights[2]);
+               
+               normalize_v3(nor);
+       }
        
-       normalize_v3(nor);
+       { /* tangent */
+               float edge[3];
+               
+               /* XXX simply using the v1-v2 edge as a tangent vector for now 
...
+                * Eventually mikktspace generated tangents (CD_TANGENT 
tessface layer)
+                * should be used for consistency, but requires well-defined 
tessface
+                * indices for the mesh surface samples.
+                */
+               
+               sub_v3_v3v3(edge, v2->co, v1->co);
+               /* make edge orthogonal to nor */
+               madd_v3_v3fl(edge, nor, -dot_v3v3(edge, nor));
+               normalize_v3_v3(tang, edge);
+       }
        
        return true;
 }
@@ -329,9 +350,9 @@ bool BKE_mesh_sample_from_particle(MSurfaceSample *sample, 
ParticleSystem *psys,
 bool BKE_mesh_sample_to_particle(MSurfaceSample *sample, ParticleSystem 
*UNUSED(psys), DerivedMesh *dm, BVHTreeFromMesh *bvhtree, ParticleData *pa)
 {
        BVHTreeNearest nearest;
-       float vec[3], nor[3];
+       float vec[3], nor[3], tang[3];
        
-       BKE_mesh_sample_eval(dm, sample, vec, nor);
+       BKE_mesh_sample_eval(dm, sample, vec, nor, tang);
        
        nearest.index = -1;
        nearest.dist_sq = FLT_MAX;
diff --git a/source/blender/bmesh/intern/bmesh_strands.c 
b/source/blender/bmesh/intern/bmesh_strands.c
index ae8fd7a..ec1b778 100644
--- a/source/blender/bmesh/intern/bmesh_strands.c
+++ b/source/blender/bmesh/intern/bmesh_strands.c
@@ -27,6 +27,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "BLI_utildefines.h"
+#include "BLI_math.h"
 #include "BLI_mempool.h"
 
 #include "bmesh.h"
@@ -115,3 +116,30 @@ int BM_strands_keys_count(BMVert *root)
        return count;
 }
 
+/* ------------------------------------------------------------------------- */
+
+/* Create a new strand */
+BMVert *BM_strands_create(BMesh *bm, int len, bool set_defaults)
+{
+       float co[3] = {0.0f, 0.0f, 0.0f};
+       
+       BMVert *root, *v, *vprev;
+       int k;
+       
+       for (k = 0; k < len; ++k) {
+               vprev = v;
+               v = BM_vert_create(bm, co, NULL, set_defaults ? BM_CREATE_NOP : 
BM_CREATE_SKIP_CD);
+               
+               zero_v3(v->no);
+               
+               /* root */
+               if (k == 0) {
+                       root = v;
+               }
+               else {
+                       /*BMEdge *e =*/ BM_edge_create(bm, vprev, v, NULL, 
set_defaults ? BM_CREATE_NOP : BM_CREATE_SKIP_CD);
+               }
+       }
+       
+       return root;
+}
diff --git a/source/blender/bmesh/intern/bmesh_strands.h 
b/source/blender/bmesh/intern/bmesh_strands.h
index 8410bfd..66284ee 100644
--- a/source/blender/bmesh/intern/bmesh_strands.h
+++ b/source/blender/bmesh/intern/bmesh_strands.h
@@ -72,6 +72,9 @@ BLI_INLINE bool BM_strands_vert_is_tip(BMVert *v)
 int BM_strands_count(BMesh *bm);
 int BM_strands_keys_count(BMVert *root);
 
+/* Create a new strand */
+struct BMVert *BM_strands_create(struct BMesh *bm, int len, bool set_defaults);
+
 /* ==== Iterators ==== */
 
 typedef enum BMStrandsIterType {
diff --git a/source/blender/bmesh/intern/bmesh_strands_conv.c 
b/source/blender/bmesh/intern/bmesh_strands_conv.c
index 786b35b..b23dbbd 100644
--- a/source/blender/bmesh/intern/bmesh_strands_conv.c
+++ b/source/blender/bmesh/intern/bmesh_strands_conv.c
@@ -76,13 +76,10 @@ void BM_strands_cd_validate(BMesh *UNUSED(bm))
 {
 }
 
-void BM_strands_cd_flag_ensure(BMesh *bm, ParticleSystem *psys, const char 
cd_flag)
+void BM_strands_cd_flag_ensure(BMesh *bm, const char cd_flag)
 {
        const char cd_flag_all = BM_strands_cd_flag_from_bmesh(bm) | cd_flag;
        BM_strands_cd_flag_apply(bm, cd_flag_all);
-       if (psys) {
-//             psys->cd_flag = cd_flag_all;
-       }
 }
 
 void BM_strands_cd_flag_apply(BMesh *bm, const char UNUSED(cd_flag))
diff --git a/source/blender/bmesh/intern/bmesh_strands_conv.h 
b/source/blender/bmesh/intern/bmesh_strands_conv.h
index 30bf139..683c1e9 100644
--- a/source/blender/bmesh/intern/bmesh_strands_conv.h
+++ b/source/blender/bmesh/intern/bmesh_strands_conv.h
@@ -45,7 +45,7 @@ extern const char *CD_HAIR_WEIGHT;
 extern const char *CD_HAIR_ROOT_LOCATION;
 
 void BM_strands_cd_validate(struct BMesh *bm);
-void BM_strands_cd_flag_ensure(struct BMesh *bm, struct ParticleSystem *psys, 
const char cd_flag);
+void BM_strands_cd_flag_ensure(struct BMesh *bm, const char cd_flag);
 void BM_strands_cd_flag_apply(struct BMesh *bm, const char cd_flag);
 char BM_strands_cd_flag_from_bmesh(struct BMesh *bm);
 
diff --git a/source/blender/editors/hair/hair_edit.c 
b/source/blender/editors/hair/hair_edit.c
index fa7e914..4912add 100644
--- a/source/blender/editors/hair/hair_edit.c
+++ b/source/blender/editors/hair/hair_edit.c
@@ -308,7 +308,6 @@ static bool hair_stroke_apply(bContext *C, wmOperator *op, 
PointerRNA *itemptr)
        HairEditSettings *settings = &scene->toolsettings->hair_edit;
        ARegion *ar = CTX_wm_region(C);
        
-       float imat[4][4];
        float mouse[2], mdelta[2], zvec[3], delta_max;
        int totsteps, step;
        HairToolData tool_d

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to