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:
Diffstat (limited to 'source/blender/editors/transform/transform_conversions.c')
-rw-r--r--source/blender/editors/transform/transform_conversions.c237
1 files changed, 233 insertions, 4 deletions
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 80d8ce67b75..d8e5f99232d 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -69,6 +69,7 @@
#include "BKE_crazyspace.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
+#include "BKE_editstrands.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
@@ -1930,6 +1931,211 @@ void flushTransParticles(TransInfo *t)
PE_update_object(scene, OBACT, 1);
}
+
+/* ******************* hair edit **************** */
+
+static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists);
+static struct TransIslandData *bmesh_islands_info_calc(BMesh *bm, short selectmode, int *r_island_tot, int **r_island_vert_map);
+
+static void StrandVertsToTransData(TransInfo *t, TransData *td,
+ BMEditStrands *UNUSED(edit), BMVert *eve, const float nor[3], const float tang[3],
+ struct TransIslandData *v_island)
+{
+ BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0);
+
+ td->flag = 0;
+ td->loc = eve->co;
+ copy_v3_v3(td->iloc, td->loc);
+
+ if (v_island) {
+ copy_v3_v3(td->center, v_island->co);
+ copy_m3_m3(td->axismtx, v_island->axismtx);
+ }
+ else if (t->around == V3D_LOCAL) {
+ copy_v3_v3(td->center, td->loc);
+ createSpaceNormalTangent(td->axismtx, nor, tang);
+ }
+ else {
+ copy_v3_v3(td->center, td->loc);
+
+ /* Setting normals */
+ copy_v3_v3(td->axismtx[2], nor);
+ td->axismtx[0][0] =
+ td->axismtx[0][1] =
+ td->axismtx[0][2] =
+ td->axismtx[1][0] =
+ td->axismtx[1][1] =
+ td->axismtx[1][2] = 0.0f;
+ }
+
+ td->ext = NULL;
+ td->val = NULL;
+ td->extra = NULL;
+}
+
+static void createTransStrandVerts(TransInfo *t)
+{
+ Scene *scene = t->scene;
+ Object *ob = OBACT;
+ BMEditStrands *edit = BKE_editstrands_from_object(ob);
+ BMesh *bm = edit->bm;
+ TransData *tob = NULL;
+ BMVert *eve;
+ BMIter iter;
+ float mtx[3][3], smtx[3][3];
+ float *dists = NULL;
+ int a;
+ int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
+ int mirror = 0;
+
+ struct TransIslandData *island_info = NULL;
+ int island_info_tot;
+ int *island_vert_map = NULL;
+
+ if (t->flag & T_MIRROR) {
+#if 0 // TODO mirror relies on EDBM functions which don't have an equivalent for editstrands yet
+ EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, false);
+ mirror = 1;
+#endif
+ }
+
+ /* quick check if we can transform */
+ /* note: in prop mode we need at least 1 selected */
+ if (bm->totvertsel == 0) {
+ goto cleanup;
+ }
+
+ if (propmode) {
+ unsigned int count = 0;
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ count++;
+ }
+ }
+
+ t->total = count;
+
+ /* allocating scratch arrays */
+ if (propmode & T_PROP_CONNECTED)
+ dists = MEM_mallocN(bm->totvert * sizeof(float), "scratch nears");
+ }
+ else {
+ t->total = bm->totvertsel;
+ }
+
+ tob = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Strands EditMode)");
+
+ copy_m3_m4(mtx, ob->obmat);
+ /* we use a pseudoinverse so that when one of the axes is scaled to 0,
+ * matrix inversion still works and we can still moving along the other */
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
+
+ if (propmode & T_PROP_CONNECTED) {
+ editmesh_set_connectivity_distance(bm, mtx, dists);
+ }
+
+ if (t->around == V3D_LOCAL) {
+ island_info = bmesh_islands_info_calc(edit->bm, SCE_SELECT_VERTEX, &island_info_tot, &island_vert_map);
+ }
+
+ /* find out which half we do */
+ if (mirror) {
+#if 0 // TODO
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve->co[0] != 0.0f) {
+ if (eve->co[0] < 0.0f) {
+ t->mirror = -1;
+ mirror = -1;
+ }
+ break;
+ }
+ }
+#endif
+ }
+
+ t->customData = BKE_editstrands_get_locations(edit);
+ t->flag |= T_FREE_CUSTOMDATA;
+
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ if (propmode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ struct TransIslandData *v_island = (island_info && island_vert_map[a] != -1) ?
+ &island_info[island_vert_map[a]] : NULL;
+ /* XXX TODO calculate normal and tangent along the strand */
+ float nor[3], tang[3];
+ nor[0] = 0.0f; nor[1] = 0.0f; nor[2] = 1.0f;
+ tang[0] = 0.0f; tang[1] = 1.0f; tang[2] = 0.0f;
+
+ StrandVertsToTransData(t, tob, edit, eve, nor, tang, v_island);
+
+ /* selected */
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT))
+ tob->flag |= TD_SELECTED;
+
+ if (propmode) {
+ if (propmode & T_PROP_CONNECTED) {
+ tob->dist = dists[a];
+ }
+ else {
+ tob->flag |= TD_NOTCONNECTED;
+ tob->dist = FLT_MAX;
+ }
+ }
+
+ copy_m3_m3(tob->smtx, smtx);
+ copy_m3_m3(tob->mtx, mtx);
+
+ /* Mirror? */
+ if ((mirror > 0 && tob->iloc[0] > 0.0f) || (mirror < 0 && tob->iloc[0] < 0.0f)) {
+#if 0 // TODO
+ BMVert *vmir = EDBM_verts_mirror_get(em, eve);
+ if (vmir && vmir != eve) {
+ tob->extra = vmir;
+ }
+#endif
+ }
+ tob++;
+ }
+ }
+ }
+
+ if (island_info) {
+ MEM_freeN(island_info);
+ MEM_freeN(island_vert_map);
+ }
+
+ if (mirror != 0) {
+#if 0 // TODO
+ tob = t->data;
+ for (a = 0; a < t->total; a++, tob++) {
+ if (ABS(tob->loc[0]) <= 0.00001f) {
+ tob->flag |= TD_MIRROR_EDGE;
+ }
+ }
+#endif
+ }
+
+cleanup:
+ if (dists)
+ MEM_freeN(dists);
+
+ if (t->flag & T_MIRROR) {
+#if 0 // TODO
+ EDBM_verts_mirror_cache_end(em);
+#endif
+ }
+}
+
+void flushTransStrands(TransInfo *t)
+{
+ Scene *scene = t->scene;
+ Object *ob = OBACT;
+ BMEditStrands *edit = BKE_editstrands_from_object(ob);
+ BMEditStrandsLocations origlocs = t->customData;
+
+ BKE_editstrands_solve_constraints(ob, edit, origlocs);
+}
+
/* ********************* mesh ****************** */
static bool bmesh_test_dist_add(BMVert *v, BMVert *v_other,
@@ -2082,9 +2288,8 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float
MEM_freeN(dists_prev);
}
-static struct TransIslandData *editmesh_islands_info_calc(BMEditMesh *em, int *r_island_tot, int **r_island_vert_map)
+static struct TransIslandData *bmesh_islands_info_calc(BMesh *bm, short selectmode, int *r_island_tot, int **r_island_vert_map)
{
- BMesh *bm = em->bm;
struct TransIslandData *trans_islands;
char htype;
char itype;
@@ -2098,7 +2303,7 @@ static struct TransIslandData *editmesh_islands_info_calc(BMEditMesh *em, int *r
int *vert_map;
- if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
+ if (selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__);
group_tot = BM_mesh_calc_edge_groups(bm, groups_array, &group_index,
NULL, NULL,
@@ -2362,7 +2567,7 @@ static void createTransEditVerts(TransInfo *t)
}
if (t->around == V3D_LOCAL) {
- island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map);
+ island_info = bmesh_islands_info_calc(em->bm, em->selectmode, &island_info_tot, &island_vert_map);
}
/* detect CrazySpace [tm] */
@@ -4827,6 +5032,7 @@ static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData *
Sequence *seq;
int recursive, count, flag;
int tot = 0;
+ int max = INT32_MIN, min = INT32_MAX;
for (seq = seqbase->first; seq; seq = seq->next) {
@@ -4849,15 +5055,21 @@ static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData *
if (flag & SEQ_LEFTSEL) {
SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_LEFTSEL);
tot++;
+ min = min_ii(seq->startdisp, min);
+ max = max_ii(seq->startdisp, max);
}
if (flag & SEQ_RIGHTSEL) {
SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_RIGHTSEL);
tot++;
+ min = min_ii(seq->enddisp, min);
+ max = max_ii(seq->enddisp, max);
}
}
else {
SeqToTransData(td++, td2d++, tdsq++, seq, flag, SELECT);
tot++;
+ min = min_ii(seq->startdisp, min);
+ max = max_ii(seq->enddisp, max);
}
}
}
@@ -6296,6 +6508,13 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
{
/* do nothing */
}
+ else if ((t->scene->basact) &&
+ (ob = t->scene->basact->object) &&
+ (ob->mode & OB_MODE_HAIR_EDIT) &&
+ BKE_editstrands_from_object(ob))
+ {
+ /* do nothing */
+ }
else { /* Objects */
int i;
@@ -8052,6 +8271,16 @@ void createTransData(bContext *C, TransInfo *t)
sort_trans_data_dist(t);
}
}
+ else if (ob && (ob->mode & OB_MODE_HAIR_EDIT) && BKE_editstrands_from_object(ob)) {
+ createTransStrandVerts(t);
+ t->flag |= T_POINTS;
+
+ if (t->data && t->flag & T_PROP_EDIT) {
+ sort_trans_data(t); // makes selected become first in array
+ set_prop_dist(t, 1);
+ sort_trans_data_dist(t);
+ }
+ }
else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
t->flag |= T_POINTS | T_2D_EDIT;