diff options
author | Darshan Kadu <darsh7807@gmail.com> | 2017-09-10 15:41:40 +0300 |
---|---|---|
committer | Darshan Kadu <darsh7807@gmail.com> | 2017-09-10 15:41:40 +0300 |
commit | 6594fa1ce02809a275c9cd488fa0223d03d73571 (patch) | |
tree | 0bcd95846e1e3b09239126b40ef434ed3dc3a50d /source/blender/editors/transform/transform_conversions.c | |
parent | f2017083a19e5c83aadc575625dce0642ffce6c5 (diff) |
merged the master branchsoc-2017-vertex_paint
Diffstat (limited to 'source/blender/editors/transform/transform_conversions.c')
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 193 |
1 files changed, 139 insertions, 54 deletions
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 04b9ae75c8f..521179fc1d9 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -771,29 +771,37 @@ int count_set_pose_transflags(int *out_mode, short around, Object *ob) /* -------- Auto-IK ---------- */ /* adjust pose-channel's auto-ik chainlen */ -static void pchan_autoik_adjust(bPoseChannel *pchan, short chainlen) +static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen) { bConstraint *con; + bool changed = false; /* don't bother to search if no valid constraints */ - if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) - return; + if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) { + return changed; + } /* check if pchan has ik-constraint */ for (con = pchan->constraints.first; con; con = con->next) { if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) { bKinematicConstraint *data = con->data; - + /* only accept if a temporary one (for auto-ik) */ if (data->flag & CONSTRAINT_IK_TEMP) { /* chainlen is new chainlen, but is limited by maximum chainlen */ - if ((chainlen == 0) || (chainlen > data->max_rootbone)) + const int old_rootbone = data->rootbone; + if ((chainlen == 0) || (chainlen > data->max_rootbone)) { data->rootbone = data->max_rootbone; - else + } + else { data->rootbone = chainlen; + } + changed |= (data->rootbone != old_rootbone); } } } + + return changed; } /* change the chain-length of auto-ik */ @@ -809,7 +817,13 @@ void transform_autoik_update(TransInfo *t, short mode) } else if (mode == -1) { /* mode==-1 is from WHEELMOUSEUP... decreases len */ - if (*chainlen > 0) (*chainlen)--; + if (*chainlen > 0) { + (*chainlen)--; + } + else { + /* IK length did not change, skip updates. */ + return; + } } /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */ @@ -817,8 +831,19 @@ void transform_autoik_update(TransInfo *t, short mode) return; /* apply to all pose-channels */ + bool changed = false; for (pchan = t->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) { - pchan_autoik_adjust(pchan, *chainlen); + changed |= pchan_autoik_adjust(pchan, *chainlen); + } + +#ifdef WITH_LEGACY_DEPSGRAPH + if (!DEG_depsgraph_use_legacy()) +#endif + { + if (changed) { + /* TODO(sergey): Consider doing partial update only. */ + DAG_relations_tag_update(G.main); + } } } @@ -1500,6 +1525,48 @@ static TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struc return hdata; } +/** + * For the purpose of transform code we need to behave as if handles are selected, + * even when they aren't (see special case below). + */ +static int bezt_select_to_transform_triple_flag( + const BezTriple *bezt, const bool hide_handles) +{ + int flag = 0; + + if (hide_handles) { + if (bezt->f2 & SELECT) { + flag = (1 << 0) | (1 << 1) | (1 << 2); + } + } + else { + flag = ( + ((bezt->f1 & SELECT) ? (1 << 0) : 0) | + ((bezt->f2 & SELECT) ? (1 << 1) : 0) | + ((bezt->f3 & SELECT) ? (1 << 2) : 0) + ); + } + + /* Special case for auto & aligned handles: + * When a center point is being moved without the handles, + * leaving the handles stationary makes no sense and only causes strange behavior, + * where one handle is arbitrarily anchored, the other one is aligned and lengthened + * based on where the center point is moved. Also a bug when cancelling, see: T52007. + * + * A more 'correct' solution could be to store handle locations in 'TransDataCurveHandleFlags'. + * However that doesn't resolve odd behavior, so best transform the handles in this case. + */ + if ((flag != ((1 << 0) | (1 << 1) | (1 << 2))) && (flag & (1 << 1))) { + if (ELEM(bezt->h1, HD_AUTO, HD_ALIGN) && + ELEM(bezt->h2, HD_AUTO, HD_ALIGN)) + { + flag = (1 << 0) | (1 << 1) | (1 << 2); + } + } + + return flag; +} + static void createTransCurveVerts(TransInfo *t) { Curve *cu = t->obedit->data; @@ -1517,22 +1584,22 @@ static void createTransCurveVerts(TransInfo *t) /* to be sure */ if (cu->editnurb == NULL) return; +#define SEL_F1 (1 << 0) +#define SEL_F2 (1 << 1) +#define SEL_F3 (1 << 2) + /* count total of vertices, check identical as in 2nd loop for making transdata! */ nurbs = BKE_curve_editNurbs_get(cu); for (nu = nurbs->first; nu; nu = nu->next) { if (nu->type == CU_BEZIER) { for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { if (bezt->hide == 0) { - if (hide_handles) { - if (bezt->f2 & SELECT) countsel += 3; - if (is_prop_edit) count += 3; - } - else { - if (bezt->f1 & SELECT) countsel++; - if (bezt->f2 & SELECT) countsel++; - if (bezt->f3 & SELECT) countsel++; - if (is_prop_edit) count += 3; - } + const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles); + if (bezt_tx & SEL_F1) { countsel++; } + if (bezt_tx & SEL_F2) { countsel++; } + if (bezt_tx & SEL_F3) { countsel++; } + if (is_prop_edit) count += 3; + } } } @@ -1583,10 +1650,10 @@ static void createTransCurveVerts(TransInfo *t) } } - if (is_prop_edit || - ((bezt->f2 & SELECT) && hide_handles) || - ((bezt->f1 & SELECT) && hide_handles == 0)) - { + /* Elements that will be transform (not always a match to selection). */ + const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles); + + if (is_prop_edit || bezt_tx & SEL_F1) { copy_v3_v3(td->iloc, bezt->vec[0]); td->loc = bezt->vec[0]; copy_v3_v3(td->center, bezt->vec[(hide_handles || @@ -1617,7 +1684,7 @@ static void createTransCurveVerts(TransInfo *t) } /* This is the Curve Point, the other two are handles */ - if (is_prop_edit || (bezt->f2 & SELECT)) { + if (is_prop_edit || bezt_tx & SEL_F2) { copy_v3_v3(td->iloc, bezt->vec[1]); td->loc = bezt->vec[1]; copy_v3_v3(td->center, td->loc); @@ -1643,7 +1710,7 @@ static void createTransCurveVerts(TransInfo *t) copy_m3_m3(td->axismtx, axismtx); } - if ((bezt->f1 & SELECT) == 0 && (bezt->f3 & SELECT) == 0) + if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0) /* If the middle is selected but the sides arnt, this is needed */ if (hdata == NULL) { /* if the handle was not saved by the previous handle */ hdata = initTransDataCurveHandles(td, bezt); @@ -1653,10 +1720,7 @@ static void createTransCurveVerts(TransInfo *t) count++; tail++; } - if (is_prop_edit || - ((bezt->f2 & SELECT) && hide_handles) || - ((bezt->f3 & SELECT) && hide_handles == 0)) - { + if (is_prop_edit || bezt_tx & SEL_F3) { copy_v3_v3(td->iloc, bezt->vec[2]); td->loc = bezt->vec[2]; copy_v3_v3(td->center, bezt->vec[(hide_handles || @@ -1711,6 +1775,26 @@ static void createTransCurveVerts(TransInfo *t) for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) { if (bp->hide == 0) { if (is_prop_edit || (bp->f1 & SELECT)) { + float axismtx[3][3]; + + if (t->around == V3D_AROUND_LOCAL_ORIGINS) { + if (nu->pntsv == 1) { + float normal[3], plane[3]; + + BKE_nurb_bpoint_calc_normal(nu, bp, normal); + BKE_nurb_bpoint_calc_plane(nu, bp, plane); + + if (createSpaceNormalTangent(axismtx, normal, plane)) { + /* pass */ + } + else { + normalize_v3(normal); + axis_dominant_v3_to_m3(axismtx, normal); + invert_m3(axismtx); + } + } + } + copy_v3_v3(td->iloc, bp->vec); td->loc = bp->vec; copy_v3_v3(td->center, td->loc); @@ -1729,6 +1813,11 @@ static void createTransCurveVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); + if (t->around == V3D_AROUND_LOCAL_ORIGINS) { + if (nu->pntsv == 1) { + copy_m3_m3(td->axismtx, axismtx); + } + } td++; count++; @@ -1744,6 +1833,10 @@ static void createTransCurveVerts(TransInfo *t) calc_distanceCurveVerts(head, tail - 1); } } + +#undef SEL_F1 +#undef SEL_F2 +#undef SEL_F3 } /* ********************* lattice *************** */ @@ -2008,9 +2101,9 @@ static bool bmesh_test_dist_add( } /** - * \parm mtx: Measure disatnce in this space. - * \parm dists: Store the closest connected distance to selected vertices. - * \parm index: Optionally store the original index we're measuring the distance to (can be NULL). + * \param mtx: Measure disatnce in this space. + * \param dists: Store the closest connected distance to selected vertices. + * \param index: Optionally store the original index we're measuring the distance to (can be NULL). */ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists, int *index) { @@ -2280,7 +2373,7 @@ static struct TransIslandData *editmesh_islands_info_calc( } if (group_tot_single != 0) { - trans_islands = MEM_reallocN(trans_islands, group_tot + group_tot_single); + trans_islands = MEM_reallocN(trans_islands, sizeof(*trans_islands) * (group_tot + group_tot_single)); BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) { @@ -2402,7 +2495,8 @@ static void createTransEditVerts(TransInfo *t) int island_info_tot; int *island_vert_map = NULL; - const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS) && (t->mode != TFM_TRANSLATION); + /* Even for translation this is needed because of island-orientation, see: T51651. */ + const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS); /* Original index of our connected vertex when connected distances are calculated. * Optional, allocate if needed. */ int *dists_index = NULL; @@ -2468,11 +2562,6 @@ static void createTransEditVerts(TransInfo *t) editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index); } - /* Only in case of rotation and resize, we want the elements of the edited - * object to behave as groups whose pivot are the individual origins - * - * TODO: use island_info to detect the closest point when the "Snap Target" - * in Blender UI is "Closest" */ if (is_island_center) { /* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */ const bool calc_single_islands = ( @@ -5353,7 +5442,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) } /* update object's loc/rot to get current rigid body transform */ mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat); - BKE_object_mat3_to_rot(ob, rot, false); + sub_v3_v3(ob->loc, ob->dloc); + BKE_object_mat3_to_rot(ob, rot, false); /* drot is already corrected here */ } } @@ -5886,27 +5976,23 @@ static void special_aftertrans_update__movieclip(bContext *C, TransInfo *t) { SpaceClip *sc = t->sa->spacedata.first; MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTrackingPlaneTrack *plane_track; ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking); - int framenr = ED_space_clip_get_clip_frame_number(sc); - - for (plane_track = plane_tracks_base->first; + const int framenr = ED_space_clip_get_clip_frame_number(sc); + /* Update coordinates of modified plane tracks. */ + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { bool do_update = false; - if (plane_track->flag & PLANE_TRACK_HIDDEN) { continue; } - do_update |= PLANE_TRACK_VIEW_SELECTED(plane_track) != 0; if (do_update == false) { if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) { int i; for (i = 0; i < plane_track->point_tracksnr; i++) { MovieTrackingTrack *track = plane_track->point_tracks[i]; - if (TRACK_VIEW_SELECTED(sc, track)) { do_update = true; break; @@ -5914,15 +6000,14 @@ static void special_aftertrans_update__movieclip(bContext *C, TransInfo *t) } } } - if (do_update) { BKE_tracking_track_plane_from_existing_motion(plane_track, framenr); } } - - if (t->scene->nodetree) { - /* tracks can be used for stabilization nodes, - * flush update for such nodes */ + if (t->scene->nodetree != NULL) { + /* Tracks can be used for stabilization nodes, + * flush update for such nodes. + */ nodeUpdateID(t->scene->nodetree, &clip->id); WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL); } @@ -7750,7 +7835,7 @@ static void createTransGPencil(bContext *C, TransInfo *t) float mtx[3][3], smtx[3][3]; const Scene *scene = CTX_data_scene(C); - const int cfra = CFRA; + const int cfra_scene = CFRA; const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0; const bool is_prop_edit_connected = (t->flag & T_PROP_CONNECTED) != 0; @@ -7775,7 +7860,7 @@ static void createTransGPencil(bContext *C, TransInfo *t) if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) { bGPDframe *gpf = gpl->actframe; bGPDstroke *gps; - + for (gps = gpf->strokes.first; gps; gps = gps->next) { /* skip strokes that are invalid for current view */ if (ED_gpencil_stroke_can_use(C, gps) == false) { @@ -7831,6 +7916,7 @@ static void createTransGPencil(bContext *C, TransInfo *t) for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { /* only editable and visible layers are considered */ if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) { + const int cfra = (gpl->flag & GP_LAYER_FRAMELOCK) ? gpl->actframe->framenum : cfra_scene; bGPDframe *gpf = gpl->actframe; bGPDstroke *gps; float diff_mat[4][4]; @@ -7847,7 +7933,6 @@ static void createTransGPencil(bContext *C, TransInfo *t) * - This is useful when animating as it saves that "uh-oh" moment when you realize you've * spent too much time editing the wrong frame... */ - // XXX: should this be allowed when framelock is enabled? if (gpf->framenum != cfra) { gpf = BKE_gpencil_frame_addcopy(gpl, cfra); /* in some weird situations (framelock enabled) return NULL */ |