Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/curve/editcurve.c
| Context not available. | |||||
| /* load editNurb in object */ | /* load editNurb in object */ | ||||
| void ED_curve_editnurb_load(Main *bmain, Object *obedit) | void ED_curve_editnurb_load(Main *bmain, Object *obedit) | ||||
| { | { | ||||
| ListBase *editnurb = object_editcurve_get(obedit); | // ListBase *editnurb = object_editcurve_get(obedit); | ||||
| if (obedit == NULL) { | |||||
| return; | |||||
| } | |||||
| if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { | |||||
| Curve *cu = obedit->data; | |||||
| Nurb *nu, *newnu; | |||||
| ListBase newnurb = {NULL, NULL}, oldnurb = cu->nurb; | |||||
| remap_hooks_and_vertex_parents(bmain, obedit); | |||||
| for (nu = editnurb->first; nu; nu = nu->next) { | Curve *cu = obedit->data; | ||||
| newnu = BKE_nurb_duplicate(nu); | ListBase *editnurb = object_editcurve_get(obedit); | ||||
| BLI_addtail(&newnurb, newnu); | // for nu in editnurb: if (nu->type == CU_NURBS) BKE_nurb_order_clamp_u(nu); | ||||
| Nurb *nu; | |||||
| if (nu->type == CU_NURBS) { | if (obedit == NULL) return; | ||||
| BKE_nurb_order_clamp_u(nu); | if (!ELEM(obedit->type, OB_CURVE, OB_SURF)) return; | ||||
| } | for (nu=(Nurb*)editnurb->first; nu; nu=nu->next) { | ||||
| } | BKE_nurbs_editKnot_propagate_ek2nurb(nu); | ||||
| } | |||||
| BKE_nurbList_duplicate(&cu->nurb, editnurb); | |||||
| /* We have to pass also new copied nurbs, since we want to restore original curve | /* We have to pass also new copied nurbs, since we want to restore original curve | ||||
| * (without edited shapekey) on obdata, but *not* on editcurve itself | * (without edited shapekey) on obdata, but *not* on editcurve itself | ||||
| * (ED_curve_editnurb_load call does not always implies freeing | * (ED_curve_editnurb_load call does not always implies freeing | ||||
| * of editcurve, e.g. when called to generate render data). */ | * of editcurve, e.g. when called to generate render data). */ | ||||
| calc_shapeKeys(obedit, &newnurb); | calc_shapeKeys(obedit, &editnurb); | ||||
| cu->nurb = newnurb; | // cu->nurb = newnurb; | ||||
| ED_curve_updateAnimPaths(bmain, obedit->data); | ED_curve_updateAnimPaths(bmain, obedit->data); | ||||
| BKE_nurbList_free(&oldnurb); | // BKE_nurbList_free(&oldnurb); | ||||
| } | // } | ||||
| } | } | ||||
| /* make copy in cu->editnurb */ | /* make copy in cu->editnurb */ | ||||
| Context not available. | |||||
| nu = cu->nurb.first; | nu = cu->nurb.first; | ||||
| while (nu) { | while (nu) { | ||||
| newnu = BKE_nurb_duplicate(nu); | newnu = BKE_nurb_duplicate(nu); | ||||
| BKE_nurb_test_2d(newnu); // after join, or any other creation of curve | BKE_nurb_ensure_2d(newnu); // after join, or any other creation of curve | ||||
| BLI_addtail(&editnurb->nurbs, newnu); | BLI_addtail(&editnurb->nurbs, newnu); | ||||
| nu = nu->next; | nu = nu->next; | ||||
| } | } | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| BKE_nurb_test_2d(nu); | BKE_nurb_ensure_2d(nu); | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| /******************** find nearest ************************/ | /******************** find nearest ************************/ | ||||
| static void ED_curve_pick_vert__doClosest( | static void ED_curve_pick_vert__doClosest( | ||||
| void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) | ViewContext *vc,void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) | ||||
| { | { | ||||
| struct { | struct { | ||||
| BPoint *bp; | BPoint *bp; | ||||
| BezTriple *bezt; | BezTriple *bezt; | ||||
| Nurb *nurb; | Nurb *nurb; | ||||
| int *dir; | |||||
| float dist; | float dist; | ||||
| int hpoint, select; | int hpoint, select; | ||||
| float mval_fl[2]; | float mval_fl[2]; | ||||
| bool is_changed; | bool is_changed; | ||||
| } *data = userData; | } *data = userData; | ||||
| int pntsu, pntsv, idx, uidx, vidx; | |||||
| float cos, max_cos; | |||||
| float compass_pt[2]; /* pos of adjacent bp in {+u,-u,+v,-v} direction */ | |||||
| float compass_dir[2]; /* bp ---> bp{+u,-u,+v,-v} */ | |||||
| float mouse_dir[2]; /* bp ---> clickpt */ | |||||
| short flag; | short flag; | ||||
| float dist_test; | float dist_test; | ||||
| BPoint *Upos, *Uneg, *Vpos, *Vneg; | |||||
| if (bp) { | if (bp) { | ||||
| flag = bp->f1; | flag = bp->f1; | ||||
| Context not available. | |||||
| data->nurb = nu; | data->nurb = nu; | ||||
| data->hpoint = bezt ? beztindex : 0; | data->hpoint = bezt ? beztindex : 0; | ||||
| data->is_changed = true; | data->is_changed = true; | ||||
| } | |||||
| if (nu->type==CU_NURBS && data->dir) { | |||||
| pntsu = (nu->pntsu<=1)? 1 : nu->pntsu; | |||||
| pntsv = (nu->pntsu<=1)? 1 : nu->pntsv; | |||||
| idx = bp - nu->bp; | |||||
| uidx = idx%pntsu; | |||||
| vidx = idx/pntsu; | |||||
| BLI_assert(0<=idx && idx<pntsu*pntsv); | |||||
| max_cos = -2.0; | |||||
| *data->dir=-1; | |||||
| sub_v2_v2v2(mouse_dir, data->mval_fl, screen_co); | |||||
| normalize_v2(mouse_dir); | |||||
| *data->dir = -1; | |||||
| Upos = (uidx<pntsu-1)? bp+1 : NULL; | |||||
| if (Upos && | |||||
| ED_view3d_project_float_object( | |||||
| vc->region, Upos->vec, compass_pt, V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == | |||||
| V3D_PROJ_RET_OK) { | |||||
| sub_v2_v2v2(compass_dir, compass_pt, screen_co); | |||||
| normalize_v2(compass_dir); | |||||
| cos = dot_v2v2(compass_dir, mouse_dir); | |||||
| /* data->dir for directional select (alt+click) 0:-v 1:+v 2:-u 3:+u */ | |||||
| if (cos>max_cos) { | |||||
| *data->dir = 3; | |||||
| max_cos = cos; | |||||
| } | |||||
| } | |||||
| Uneg = (uidx>0)? bp-1 : NULL; | |||||
| if (Uneg && | |||||
| ED_view3d_project_float_object( | |||||
| vc->region, Uneg->vec, compass_pt, V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == | |||||
| V3D_PROJ_RET_OK) { | |||||
| sub_v2_v2v2(compass_dir, compass_pt, screen_co); | |||||
| normalize_v2(compass_dir); | |||||
| cos = dot_v2v2(compass_dir, mouse_dir); | |||||
| /* data->dir for directional select (alt+click) 0:-v 1:+v 2:-u 3:+u */ | |||||
| if (cos>max_cos) { | |||||
| *data->dir = 2; | |||||
| max_cos = cos; | |||||
| } | |||||
| } | |||||
| Vpos = (vidx<pntsv-1)? bp+pntsu : NULL; | |||||
| if (Vpos && | |||||
| ED_view3d_project_float_object( | |||||
| vc->region, Vpos->vec, compass_pt, V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == | |||||
| V3D_PROJ_RET_OK) { | |||||
| sub_v2_v2v2(compass_dir, compass_pt, screen_co); | |||||
| normalize_v2(compass_dir); | |||||
| cos = dot_v2v2(compass_dir, mouse_dir); | |||||
| /* data->dir for directional select (alt+click) 0:-v 1:+v 2:-u 3:+u */ | |||||
| if (cos>max_cos) { | |||||
| *data->dir = 1; | |||||
| max_cos = cos; | |||||
| } | |||||
| } | |||||
| Vneg = (vidx>0)? bp-pntsu : NULL; | |||||
| if (Vneg && | |||||
| ED_view3d_project_float_object( | |||||
| vc->region, Vneg->vec, compass_pt, V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == | |||||
| V3D_PROJ_RET_OK) { | |||||
| sub_v2_v2v2(compass_dir, compass_pt, screen_co); | |||||
| normalize_v2(compass_dir); | |||||
| cos = dot_v2v2(compass_dir, mouse_dir); | |||||
| /* data->dir for directional select (alt+click) 0:-v 1:+v 2:-u 3:+u */ | |||||
| if (cos>max_cos) { | |||||
| *data->dir = 0; | |||||
| max_cos = cos; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| bool ED_curve_pick_vert(ViewContext *vc, | bool ED_curve_pick_vert(ViewContext *vc, | ||||
| Context not available. | |||||
| BezTriple **r_bezt, | BezTriple **r_bezt, | ||||
| BPoint **r_bp, | BPoint **r_bp, | ||||
| short *r_handle, | short *r_handle, | ||||
| Base **r_base) | Base **r_base, | ||||
| int *dir) | |||||
| { | { | ||||
| /* (sel == 1): selected gets a disadvantage */ | /* (sel == 1): selected gets a disadvantage */ | ||||
| /* in nurb and bezt or bp the nearest is written */ | /* in nurb and bezt or bp the nearest is written */ | ||||
| Context not available. | |||||
| BPoint *bp; | BPoint *bp; | ||||
| BezTriple *bezt; | BezTriple *bezt; | ||||
| Nurb *nurb; | Nurb *nurb; | ||||
| int *dir; | |||||
| float dist; | float dist; | ||||
| int hpoint, select; | int hpoint, select; | ||||
| float mval_fl[2]; | float mval_fl[2]; | ||||
| Context not available. | |||||
| data.select = sel; | data.select = sel; | ||||
| data.mval_fl[0] = vc->mval[0]; | data.mval_fl[0] = vc->mval[0]; | ||||
| data.mval_fl[1] = vc->mval[1]; | data.mval_fl[1] = vc->mval[1]; | ||||
| data.dir = dir; | |||||
| uint bases_len; | uint bases_len; | ||||
| Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data( | Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data( | ||||
| Context not available. | |||||
| /***************** pick select from 3d view **********************/ | /***************** pick select from 3d view **********************/ | ||||
| bool ED_curve_editnurb_select_pick( | bool ED_curve_editnurb_select_pick( | ||||
| bContext *C, const int mval[2], bool extend, bool deselect, bool toggle) | bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, bool alt) | ||||
| { | { | ||||
| Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | ||||
| ViewContext vc; | ViewContext vc; | ||||
| Context not available. | |||||
| BPoint *bp = NULL; | BPoint *bp = NULL; | ||||
| Base *basact = NULL; | Base *basact = NULL; | ||||
| short hand; | short hand; | ||||
| int dir; /* for directional select (alt+click) 0:-v 1:+v 2:-u 3:+u */ | |||||
| view3d_operator_needs_opengl(C); | view3d_operator_needs_opengl(C); | ||||
| ED_view3d_viewcontext_init(C, &vc, depsgraph); | ED_view3d_viewcontext_init(C, &vc, depsgraph); | ||||
| copy_v2_v2_int(vc.mval, mval); | copy_v2_v2_int(vc.mval, mval); | ||||
| if (ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, &hand, &basact)) { | if (ED_curve_pick_vert(&vc, 1, &nu, &bezt, &bp, &hand, &basact, &dir)) { | ||||
| Object *obedit = basact->object; | Object *obedit = basact->object; | ||||
| Curve *cu = obedit->data; | Curve *cu = obedit->data; | ||||
| ListBase *editnurb = object_editcurve_get(obedit); | ListBase *editnurb = object_editcurve_get(obedit); | ||||
| Context not available. | |||||
| BKE_curve_nurb_vert_active_set(cu, nu, bezt); | BKE_curve_nurb_vert_active_set(cu, nu, bezt); | ||||
| } | } | ||||
| else { | else { | ||||
| select_bpoint(bp, SELECT, SELECT, HIDDEN); | |||||
| BKE_curve_nurb_vert_active_set(cu, nu, bp); | BKE_curve_nurb_vert_active_set(cu, nu, bp); | ||||
| if (nu->type==CU_NURBS && alt) { /* Loop select */ | |||||
| nurbs_select_bpoint(nu, bp, dir, SELECT, SELECT, HIDDEN); | |||||
| } else { /* Just select bp */ | |||||
| select_bpoint(bp, SELECT, SELECT, HIDDEN); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| else if (deselect) { | else if (deselect) { | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (nu->type==CU_NURBS && alt) { /* Loop select */ | |||||
| nurbs_select_bpoint(nu, bp, dir, DESELECT, SELECT, HIDDEN); | |||||
| } else { /* Just select bp */ | |||||
| select_bpoint(bp, DESELECT, SELECT, HIDDEN); | select_bpoint(bp, DESELECT, SELECT, HIDDEN); | ||||
| } | |||||
| if (bp == vert) { | if (bp == vert) { | ||||
| cu->actvert = CU_ACT_NONE; | cu->actvert = CU_ACT_NONE; | ||||
| } | } | ||||
| Context not available. | |||||
| } | } | ||||
| else { | else { | ||||
| if (bp->f1 & SELECT) { | if (bp->f1 & SELECT) { | ||||
| if (nu->type==CU_NURBS && alt) { /* Loop select */ | |||||
| nurbs_select_bpoint(nu, bp, dir, DESELECT, SELECT, HIDDEN); | |||||
| } else { /* Just select bp */ | |||||
| select_bpoint(bp, DESELECT, SELECT, HIDDEN); | select_bpoint(bp, DESELECT, SELECT, HIDDEN); | ||||
| } | |||||
| if (bp == vert) { | if (bp == vert) { | ||||
| cu->actvert = CU_ACT_NONE; | cu->actvert = CU_ACT_NONE; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (nu->type==CU_NURBS && alt) { /* Loop select */ | |||||
| nurbs_select_bpoint(nu, bp, dir, SELECT, SELECT, HIDDEN); | |||||
| } else { /* Just select bp */ | |||||
| select_bpoint(bp, SELECT, SELECT, HIDDEN); | select_bpoint(bp, SELECT, SELECT, HIDDEN); | ||||
| } | |||||
| BKE_curve_nurb_vert_active_set(cu, nu, bp); | BKE_curve_nurb_vert_active_set(cu, nu, bp); | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| BKE_curve_nurb_vert_active_set(cu, nu, bezt); | BKE_curve_nurb_vert_active_set(cu, nu, bezt); | ||||
| } | } | ||||
| else { | else { | ||||
| select_bpoint(bp, SELECT, SELECT, HIDDEN); | |||||
| BKE_curve_nurb_vert_active_set(cu, nu, bp); | BKE_curve_nurb_vert_active_set(cu, nu, bp); | ||||
| if (nu->type==CU_NURBS && alt) { /* Loop select */ | |||||
| nurbs_select_bpoint(nu, bp, dir, SELECT, SELECT, HIDDEN); | |||||
| } else { /* Just select bp */ | |||||
| select_bpoint(bp, SELECT, SELECT, HIDDEN); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| BEZT_DESEL_ALL(bezt); | BEZT_DESEL_ALL(bezt); | ||||
| nurb_new = BKE_nurb_copy(nu, 1, 1); | nurb_new = BKE_nurb_copy(nu, 1, 1); | ||||
| nurb_new->flagu &= ~CU_NURB_CYCLIC; | nurb_new->flagu &= ~CU_NURB_CYCLIC; | ||||
| nurb_new->editknot = NULL; | |||||
| BLI_addtail(&editnurb->nurbs, nurb_new); | BLI_addtail(&editnurb->nurbs, nurb_new); | ||||
| bezt_new = nurb_new->bezt; | bezt_new = nurb_new->bezt; | ||||
| ED_curve_beztcpy(editnurb, bezt_new, bezt, 1); | ED_curve_beztcpy(editnurb, bezt_new, bezt, 1); | ||||
| Context not available. | |||||
| bp->f1 &= ~SELECT; | bp->f1 &= ~SELECT; | ||||
| nurb_new = BKE_nurb_copy(nu, 1, 1); | nurb_new = BKE_nurb_copy(nu, 1, 1); | ||||
| nurb_new->flagu &= ~CU_NURB_CYCLIC; | nurb_new->flagu &= ~CU_NURB_CYCLIC; | ||||
| nurb_new->editknot = NULL; | |||||
| BLI_addtail(&editnurb->nurbs, nurb_new); | BLI_addtail(&editnurb->nurbs, nurb_new); | ||||
| bp_new = nurb_new->bp; | bp_new = nurb_new->bp; | ||||
| ED_curve_bpcpy(editnurb, bp_new, bp, 1); | ED_curve_bpcpy(editnurb, bp_new, bp, 1); | ||||
| Context not available. | |||||
| nurb_new->resolu = cu->resolu; | nurb_new->resolu = cu->resolu; | ||||
| nurb_new->orderu = 4; | nurb_new->orderu = 4; | ||||
| nurb_new->flag |= CU_SMOOTH; | nurb_new->flag |= CU_SMOOTH; | ||||
| nurb_new->editknot = NULL; | |||||
| BKE_nurb_bezierPoints_add(nurb_new, 1); | BKE_nurb_bezierPoints_add(nurb_new, 1); | ||||
| if ((cu->flag & CU_3D) == 0) { | if ((cu->flag & CU_3D) == 0) { | ||||
| Context not available. | |||||
| nurb_new->resolu = cu->resolu; | nurb_new->resolu = cu->resolu; | ||||
| nurb_new->flag |= CU_SMOOTH; | nurb_new->flag |= CU_SMOOTH; | ||||
| nurb_new->orderu = 4; | nurb_new->orderu = 4; | ||||
| nurb_new->editknot = NULL; | |||||
| BKE_nurb_points_add(nurb_new, 1); | BKE_nurb_points_add(nurb_new, 1); | ||||
| if ((cu->flag & CU_3D) == 0) { | if ((cu->flag & CU_3D) == 0) { | ||||
| nurb_new->flag |= CU_2D; | nurb_new->flag |= CU_2D; | ||||
| } | } | ||||
| } | } | ||||
| BKE_nurbs_cached_UV_mesh_clear(nurb_new, false); | |||||
| BLI_addtail(&editnurb->nurbs, nurb_new); | BLI_addtail(&editnurb->nurbs, nurb_new); | ||||
| bp_new = nurb_new->bp; | bp_new = nurb_new->bp; | ||||
| Context not available. | |||||