Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2014-12-05 16:42:22 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2015-04-20 13:23:15 +0300
commit56a09434c533e5ca72d2f8ff6e144bfcdd88886c (patch)
tree9ca26e1fc412da4c3cd21fba2334af8a89103105 /source/blender/editors/hair
parent8672304e30a207767888b75ebe9015ad7f3210a3 (diff)
Basic Add tool for creating new strands in hair edit mode.
Diffstat (limited to 'source/blender/editors/hair')
-rw-r--r--source/blender/editors/hair/hair_edit.c8
-rw-r--r--source/blender/editors/hair/hair_intern.h1
-rw-r--r--source/blender/editors/hair/hair_stroke.c115
3 files changed, 113 insertions, 11 deletions
diff --git a/source/blender/editors/hair/hair_edit.c b/source/blender/editors/hair/hair_edit.c
index fa7e914b5ee..4912adde524 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_data;
@@ -316,8 +315,6 @@ static bool hair_stroke_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
RNA_float_get_array(itemptr, "mouse", mouse);
- invert_m4_m4(imat, ob->obmat);
-
if (stroke->first) {
copy_v2_v2(stroke->lastmouse, mouse);
stroke->first = false;
@@ -338,6 +335,7 @@ static bool hair_stroke_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
tool_data.edit = edit;
tool_data.settings = settings;
+ invert_m4_m4(tool_data.imat, ob->obmat);
copy_v2_v2(tool_data.mval, mouse);
tool_data.mdepth = stroke->zfac;
@@ -345,8 +343,8 @@ static bool hair_stroke_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
ED_view3d_win_to_3d(ar, zvec, mouse, tool_data.loc);
ED_view3d_win_to_delta(ar, mdelta, tool_data.delta, stroke->zfac);
/* tools work in object space */
- mul_m4_v3(imat, tool_data.loc);
- mul_mat3_m4_v3(imat, tool_data.delta);
+ mul_m4_v3(tool_data.imat, tool_data.loc);
+ mul_mat3_m4_v3(tool_data.imat, tool_data.delta);
for (step = 0; step < totsteps; ++step) {
bool step_updated = hair_brush_step(&tool_data);
diff --git a/source/blender/editors/hair/hair_intern.h b/source/blender/editors/hair/hair_intern.h
index 7218fa08483..92b40fd083f 100644
--- a/source/blender/editors/hair/hair_intern.h
+++ b/source/blender/editors/hair/hair_intern.h
@@ -73,6 +73,7 @@ typedef struct HairToolData {
float mdepth; /* mouse z depth */
/* object space */
+ float imat[4][4]; /* obmat inverse */
float loc[3]; /* start location */
float delta[3]; /* stroke step */
} HairToolData;
diff --git a/source/blender/editors/hair/hair_stroke.c b/source/blender/editors/hair/hair_stroke.c
index e7b095e9c85..ec34475fc94 100644
--- a/source/blender/editors/hair/hair_stroke.c
+++ b/source/blender/editors/hair/hair_stroke.c
@@ -37,12 +37,15 @@
#include "BLI_math.h"
#include "DNA_brush_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
#include "BKE_brush.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_edithair.h"
+#include "BKE_mesh_sample.h"
#include "bmesh.h"
@@ -163,10 +166,102 @@ static void hair_vertex_comb(HairToolData *data, void *userdata, BMVert *v, floa
madd_v3_v3fl(v->co, data->delta, combfactor);
}
+
+BLI_INLINE void construct_m4_loc_nor_tan(float mat[4][4], const float loc[3], const float nor[3], const float tang[3])
+{
+ float cotang[3];
+
+ cross_v3_v3v3(cotang, nor, tang);
+
+ copy_v3_v3(mat[0], tang);
+ copy_v3_v3(mat[1], cotang);
+ copy_v3_v3(mat[2], nor);
+ copy_v3_v3(mat[3], loc);
+ mat[0][3] = 0.0f;
+ mat[1][3] = 0.0f;
+ mat[2][3] = 0.0f;
+ mat[3][3] = 1.0f;
+}
+
+static void grow_hair(BMEditStrands *edit, MSurfaceSample *sample)
+{
+ DerivedMesh *dm = edit->root_dm;
+ const float len = 1.5f;
+
+ float root_mat[4][4];
+ BMVert *root, *v;
+ BMIter iter;
+ int i;
+
+ {
+ float co[3], nor[3], tang[3];
+ BKE_mesh_sample_eval(dm, sample, co, nor, tang);
+ construct_m4_loc_nor_tan(root_mat, co, nor, tang);
+ }
+
+ root = BM_strands_create(edit->bm, 5, true);
+
+ BM_elem_meshsample_data_named_set(&edit->bm->vdata, root, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, sample);
+
+ BM_ITER_STRANDS_ELEM_INDEX(v, &iter, root, BM_VERTS_OF_STRAND, i) {
+ float co[3];
+
+ co[0] = co[1] = 0.0f;
+ co[2] = len * (float)i / (float)(len - 1);
+
+ mul_m4_v3(root_mat, co);
+
+ copy_v3_v3(v->co, co);
+ }
+
+ BM_mesh_elem_index_ensure(edit->bm, BM_ALL);
+}
+
+static bool hair_add_ray_cb(void *vdata, float ray_start[3], float ray_end[3])
+{
+ HairToolData *data = vdata;
+ ViewContext *vc = &data->viewdata.vc;
+
+ ED_view3d_win_to_segment(vc->ar, vc->v3d, data->mval, ray_start, ray_end, true);
+
+ mul_m4_v3(data->imat, ray_start);
+ mul_m4_v3(data->imat, ray_end);
+
+ return true;
+}
+
+static bool hair_get_surface_sample(HairToolData *data, MSurfaceSample *sample)
+{
+ DerivedMesh *dm = data->edit->root_dm;
+
+ MSurfaceSampleStorage dst;
+ int tot;
+
+ BKE_mesh_sample_storage_single(&dst, sample);
+ tot = BKE_mesh_sample_generate_raycast(&dst, dm, hair_add_ray_cb, data, 1);
+ BKE_mesh_sample_storage_release(&dst);
+
+ return tot > 0;
+}
+
+static bool hair_add(HairToolData *data)
+{
+ MSurfaceSample sample;
+
+ if (!hair_get_surface_sample(data, &sample))
+ return false;
+
+ grow_hair(data->edit, &sample);
+
+ return true;
+}
+
+
bool hair_brush_step(HairToolData *data)
{
Brush *brush = data->settings->brush;
BrushHairTool hair_tool = brush->hair_tool;
+ BMEditStrands *edit = data->edit;
int tot = 0;
switch (hair_tool) {
@@ -181,12 +276,20 @@ bool hair_brush_step(HairToolData *data)
tot = hair_tool_apply_vertex(data, hair_vertex_comb, &combdata);
break;
}
- case HAIR_TOOL_CUT: break;
- case HAIR_TOOL_LENGTH: break;
- case HAIR_TOOL_PUFF: break;
- case HAIR_TOOL_ADD: break;
- case HAIR_TOOL_SMOOTH: break;
- case HAIR_TOOL_WEIGHT: break;
+ case HAIR_TOOL_CUT:
+ break;
+ case HAIR_TOOL_LENGTH:
+ break;
+ case HAIR_TOOL_PUFF:
+ break;
+ case HAIR_TOOL_ADD:
+ if (hair_add(data))
+ edit->flag |= BM_STRANDS_DIRTY_SEGLEN;
+ break;
+ case HAIR_TOOL_SMOOTH:
+ break;
+ case HAIR_TOOL_WEIGHT:
+ break;
}
return tot > 0;