Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/curve/editcurve.c
| Context not available. | |||||
| * | * | ||||
| * The Original Code is: all of this file. | * The Original Code is: all of this file. | ||||
| * | * | ||||
| * Contributor(s): none yet. | * Contributor(s): John Roper | ||||
| * | * | ||||
| * ***** END GPL LICENSE BLOCK ***** | * ***** END GPL LICENSE BLOCK ***** | ||||
| */ | */ | ||||
| Context not available. | |||||
| RNA_def_int(ot->srna, "offset", 0, INT_MIN, INT_MAX, "Offset", "", -100, 100); | RNA_def_int(ot->srna, "offset", 0, INT_MIN, INT_MAX, "Offset", "", -100, 100); | ||||
| } | } | ||||
| /********************** select similar vertices ********************/ | |||||
| //todo: make the same enum available instead of defining it twice | |||||
| enum { | |||||
| SIM_CMP_EQ = 0, | |||||
| SIM_CMP_GT, | |||||
| SIM_CMP_LT | |||||
| }; | |||||
| static EnumPropertyItem curve_prop_similar_compare_types[] = { | |||||
| {SIM_CMP_EQ, "EQUAL", 0, "Equal", ""}, | |||||
| {SIM_CMP_GT, "GREATER", 0, "Greater", ""}, | |||||
| {SIM_CMP_LT, "LESS", 0, "Less", ""}, | |||||
| {0, NULL, 0, NULL, NULL} | |||||
| }; | |||||
| enum { | |||||
| SIMCURHAND_WEIGHT = 0, | |||||
| SIMCURHAND_TYPE, | |||||
| SIMCURHAND_DIRECTION, | |||||
| SIMCURHAND_RADIUS | |||||
| //SIMCURHAND_TILT | |||||
| }; | |||||
| static EnumPropertyItem curve_prop_similar_types[] = { | |||||
| {SIMCURHAND_WEIGHT, "WEIGHT", 0, "Weight", ""}, | |||||
| {SIMCURHAND_TYPE, "TYPE", 0, "Type", ""}, | |||||
| {SIMCURHAND_DIRECTION, "DIRECTION", 0, "Direction", ""}, | |||||
| {SIMCURHAND_RADIUS, "RADIUS", 0, "Radius", ""}, | |||||
| //{SIMCURHAND_TILT, "TILT", 0, "Tilt", ""}, | |||||
| {0, NULL, 0, NULL, NULL} | |||||
| }; | |||||
| static bool ED_curve_direction_bezt(BezTriple *bezt, float r_dir[3]) | |||||
| { | |||||
| sub_v3_v3v3(r_dir, bezt->vec[2], bezt->vec[1]); | |||||
| normalize_v3(r_dir); | |||||
| return true; | |||||
| } | |||||
| static bool ED_curve_direction_bp(Nurb *nu, BPoint *bp, float r_dir[3]) | |||||
| { | |||||
| BPoint *next_bp; | |||||
| int uvs; | |||||
| uvs = nu->pntsu * nu->pntsv; | |||||
| next_bp = BKE_nurb_bpoint_get_next(nu, bp); | |||||
| if (next_bp == NULL) { | |||||
| if (uvs > 1) { | |||||
| /* We've an ending vert */ | |||||
| /* Set the direction similar to the previous point */ | |||||
| next_bp = bp; | |||||
| bp = bp - 1; | |||||
| } | |||||
| else { | |||||
| /* We've a single vert, set the r_dir to zero and return false */ | |||||
| zero_v3(r_dir); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| /* calculate the direction */ | |||||
| sub_v3_v3v3(r_dir, (float*)next_bp->vec, (float*)bp->vec); | |||||
| normalize_v3(r_dir); | |||||
| return true; | |||||
| } | |||||
| static void ED_curve_select_similar_direction_bezt(Nurb *nu, float act_dir[3], float align) | |||||
| { | |||||
| BezTriple *bezt; | |||||
| float dir[3]; | |||||
| int a; | |||||
| /* Support till 360deg alignment*/ | |||||
| align = align * 2; | |||||
| bezt = nu->bezt; | |||||
| a = nu->pntsu; | |||||
| while (a--) { | |||||
| if (!bezt->hide) { | |||||
| /* Check the direction */ | |||||
| ED_curve_direction_bezt(bezt, dir); | |||||
| if ((1 - dot_v3v3(act_dir, dir)) <= align) { | |||||
| select_beztriple(bezt, SELECT, SELECT, VISIBLE); | |||||
| } | |||||
| } | |||||
| bezt++; | |||||
| } | |||||
| } | |||||
| static void ED_curve_select_similar_direction_bp(Nurb *nu, float act_dir[3], float align) | |||||
| { | |||||
| BPoint *bp; | |||||
| float dir[3]; | |||||
| int a; | |||||
| /* Support till 360deg alignment*/ | |||||
| align = align * 2; | |||||
| bp = nu->bp; | |||||
| a = nu->pntsu * nu->pntsv; | |||||
| while (a--) { | |||||
| if (!bp->hide) { | |||||
| /* Check the direction */ | |||||
| if (!ED_curve_direction_bp(nu, bp, dir)){ | |||||
| continue; | |||||
| } | |||||
| if ((1 - dot_v3v3(act_dir, dir)) <= align) { | |||||
| select_bpoint(bp, SELECT, SELECT, VISIBLE); | |||||
| } | |||||
| } | |||||
| bp++; | |||||
| } | |||||
| } | |||||
| static bool ED_curve_select_similar_direction(ListBase *editnurb, Curve *cu, float align) | |||||
| { | |||||
| Nurb *nu, *act_nu; | |||||
| void *act_vert; | |||||
| float dir[3]; | |||||
| /* Get active vert */ | |||||
| if (!BKE_curve_nurb_vert_active_get(cu, &act_nu, &act_vert)) | |||||
| return false; | |||||
| /* Get the active point direction */ | |||||
| if (act_nu->type == CU_BEZIER) { | |||||
| ED_curve_direction_bezt((BezTriple *)act_vert, dir); | |||||
| } | |||||
| else { | |||||
| if (!ED_curve_direction_bp(act_nu, (BPoint *)act_vert, dir)) { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| for (nu = editnurb->first; nu; nu = nu->next) { | |||||
| if (nu->type == CU_BEZIER) { | |||||
| ED_curve_select_similar_direction_bezt(nu, dir, align); | |||||
| } | |||||
| else { | |||||
| ED_curve_select_similar_direction_bp(nu, dir, align); | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| static void ED_curve_select_similar_radius_bezt(Nurb *nu, float act_radius, int compare, float thresh) | |||||
| { | |||||
| BezTriple *bezt; | |||||
| int a; | |||||
| float radius; | |||||
| bezt = nu->bezt; | |||||
| a = nu->pntsu; | |||||
| while (a--) { | |||||
| if (!bezt->hide) { | |||||
| radius = bezt->radius; | |||||
| /* Check the radius */ | |||||
| if (((0 < (act_radius - radius)) && ((act_radius - radius) < thresh) && (compare == SIM_CMP_LT)) || | |||||
| ((radius == act_radius) && (compare == SIM_CMP_EQ)) || | |||||
| ((0 < (radius - act_radius)) && ((radius - act_radius) < thresh) && (compare == SIM_CMP_GT))) { | |||||
| select_beztriple(bezt, SELECT, SELECT, VISIBLE); | |||||
| } | |||||
| } | |||||
| bezt++; | |||||
| } | |||||
| } | |||||
| static void ED_curve_select_similar_radius_bp(Nurb *nu, float act_radius, int compare, float thresh) | |||||
| { | |||||
| BPoint *bp; | |||||
| int a; | |||||
| float radius; | |||||
| bp = nu->bp; | |||||
| a = nu->pntsu * nu->pntsv; | |||||
| while (a--) { | |||||
| if (!bp->hide) { | |||||
| radius = bp->radius; | |||||
| /* Check the radius */ | |||||
| if (((0 < (act_radius - radius)) && ((act_radius - radius) < thresh) && (compare == SIM_CMP_LT)) || | |||||
| ((radius == act_radius) && (compare == SIM_CMP_EQ)) || | |||||
| ((0 < (radius - act_radius)) && ((radius - act_radius) < thresh) && (compare == SIM_CMP_GT))) { | |||||
| select_bpoint(bp, SELECT, SELECT, VISIBLE); | |||||
| } | |||||
| } | |||||
| bp++; | |||||
| } | |||||
| } | |||||
| static bool ED_curve_select_similar_radius(ListBase *editnurb, Curve *cu, float compare, float thresh) | |||||
| { | |||||
| Nurb *nu, *act_nu; | |||||
| void *act_vert; | |||||
| float radius; | |||||
| /* Get active vert */ | |||||
| if (!BKE_curve_nurb_vert_active_get(cu, &act_nu, &act_vert)) | |||||
| return false; | |||||
| /* Get the active point radius */ | |||||
| if (act_nu->type == CU_BEZIER) { | |||||
| radius = ((BezTriple *)act_vert)->radius; | |||||
| } | |||||
| else { | |||||
| radius = ((BPoint *)act_vert)->radius; | |||||
| } | |||||
| for (nu = editnurb->first; nu; nu = nu->next) { | |||||
| if (nu->type == CU_BEZIER) { | |||||
| ED_curve_select_similar_radius_bezt(nu, radius, compare, thresh); | |||||
| } | |||||
| else { | |||||
| ED_curve_select_similar_radius_bp(nu, radius, compare, thresh); | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| /* | |||||
| static void ED_curve_select_similar_tilt_bezt(Nurb *nu, float act_tilt, float align) | |||||
| { | |||||
| BezTriple *bezt; | |||||
| int a; | |||||
| float tilt; | |||||
| act_tilt = act_tilt; | |||||
| bezt = nu->bezt; | |||||
| a = nu->pntsu; | |||||
| while (a--) { | |||||
| if (!bezt->hide) { | |||||
| tilt = bezt->alfa; | |||||
| if (cos(tilt - act_tilt) <= align) { | |||||
| select_beztriple(bezt, SELECT, SELECT, VISIBLE); | |||||
| } | |||||
| } | |||||
| bezt++; | |||||
| } | |||||
| } | |||||
| static void ED_curve_select_similar_tilt_bp(Nurb *nu, float act_tilt, float align) | |||||
| { | |||||
| BPoint *bp; | |||||
| int a; | |||||
| float tilt; | |||||
| bp = nu->bp; | |||||
| a = nu->pntsu * nu->pntsv; | |||||
| while (a--) { | |||||
| if (!bp->hide) { | |||||
| tilt = bp->alfa; | |||||
| if (cos(tilt - act_tilt) <= align) { | |||||
| select_bpoint(bp, SELECT, SELECT, VISIBLE); | |||||
| } | |||||
| } | |||||
| bp++; | |||||
| } | |||||
| } | |||||
| static bool ED_curve_select_similar_tilt(ListBase *editnurb, Curve *cu, float align) | |||||
| { | |||||
| Nurb *nu, *act_nu; | |||||
| void *act_vert; | |||||
| float tilt; | |||||
| if (!BKE_curve_nurb_vert_active_get(cu, &act_nu, &act_vert)) | |||||
| return false; | |||||
| if (act_nu->type == CU_BEZIER) { | |||||
| tilt = ((BezTriple *)act_vert)->alfa; | |||||
| } | |||||
| else { | |||||
| tilt = ((BPoint *)act_vert)->alfa; | |||||
| } | |||||
| for (nu = editnurb->first; nu; nu = nu->next) { | |||||
| if (nu->type == CU_BEZIER) { | |||||
| ED_curve_select_similar_tilt_bezt(nu, tilt, align); | |||||
| } | |||||
| else { | |||||
| ED_curve_select_similar_tilt_bp(nu, tilt, align); | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| */ | |||||
| static void ED_curve_select_similar_weight_bezt(Nurb *nu, float act_weight, int compare, float thresh) | |||||
| { | |||||
| BezTriple *bezt; | |||||
| int a; | |||||
| float weight; | |||||
| bezt = nu->bezt; | |||||
| a = nu->pntsu; | |||||
| while (a--) { | |||||
| if (!bezt->hide) { | |||||
| weight = bezt->weight; | |||||
| /* Check the weight */ | |||||
| if (((0 < (act_weight - weight)) && ((act_weight - weight) < thresh) && (compare == SIM_CMP_LT)) || | |||||
| ((weight == act_weight) && (compare == SIM_CMP_EQ)) || | |||||
| ((0 < (weight - act_weight)) && ((weight - act_weight) < thresh) && (compare == SIM_CMP_GT))) { | |||||
| select_beztriple(nu->bezt, SELECT, SELECT, VISIBLE); | |||||
| } | |||||
| } | |||||
| bezt++; | |||||
| } | |||||
| } | |||||
| static void ED_curve_select_similar_weight_bp(Nurb *nu, float act_weight, int compare, float thresh) | |||||
| { | |||||
| BPoint *bp; | |||||
| int a; | |||||
| float weight; | |||||
| bp = nu->bp; | |||||
| a = nu->pntsu * nu->pntsv; | |||||
| while (a--) { | |||||
| if (!bp->hide) { | |||||
| weight = bp->weight; | |||||
| /* Check the weight */ | |||||
| if (((0 < (act_weight - weight)) && ((act_weight - weight) < thresh) && (compare == SIM_CMP_LT)) || | |||||
| + ((weight == act_weight) && (compare == SIM_CMP_EQ)) || | |||||
| ((0 < (weight - act_weight)) && ((weight - act_weight) < thresh) && (compare == SIM_CMP_GT))) { | |||||
| select_beztriple(nu->bezt, SELECT, SELECT, VISIBLE); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| static bool ED_curve_select_similar_weight(ListBase *editnurb, Curve *cu, float compare, float thresh) | |||||
| { | |||||
| Nurb *nu, *act_nu; | |||||
| void *act_vert; | |||||
| float weight; | |||||
| /* Get active vert */ | |||||
| if (!BKE_curve_nurb_vert_active_get(cu, &act_nu, &act_vert)) | |||||
| return false; | |||||
| /* Get the active point weight */ | |||||
| if (act_nu->type == CU_BEZIER) { | |||||
| weight = ((BezTriple *)act_vert)->weight; | |||||
| } | |||||
| else { | |||||
| weight = ((BPoint *)act_vert)->weight; | |||||
| } | |||||
| for (nu = editnurb->first; nu; nu = nu->next) { | |||||
| if (nu->type == CU_BEZIER) { | |||||
| ED_curve_select_similar_weight_bezt(nu, weight, compare, thresh); | |||||
| } | |||||
| else { | |||||
| ED_curve_select_similar_weight_bp(nu, weight, compare, thresh); | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| static void ED_curve_select_all_bezt(Nurb *nu) | |||||
| { | |||||
| BezTriple *bezt; | |||||
| int a; | |||||
| bezt = nu->bezt; | |||||
| a = nu->pntsu; | |||||
| while (a--) { | |||||
| if (!bezt->hide) { | |||||
| select_beztriple(bezt, SELECT, SELECT, VISIBLE); | |||||
| } | |||||
| bezt++; | |||||
| } | |||||
| } | |||||
| static void ED_curve_select_all_bp(Nurb *nu) | |||||
| { | |||||
| BPoint *bp; | |||||
| int a; | |||||
| bp = nu->bp; | |||||
| a = nu->pntsu * nu->pntsv; | |||||
| while (a--) { | |||||
| if (!bp->hide) { | |||||
| select_bpoint(bp, SELECT, SELECT, VISIBLE); | |||||
| } | |||||
| bp++; | |||||
| } | |||||
| } | |||||
| static bool ED_curve_select_similar_type(ListBase *editnurb, Curve *cu) | |||||
| { | |||||
| Nurb *nu, *act_nu; | |||||
| int type; | |||||
| /* Get active nurb type */ | |||||
| act_nu = BKE_curve_nurb_active_get(cu); | |||||
| if (!act_nu) | |||||
| return false; | |||||
| /* Get the active nurb type */ | |||||
| type = act_nu->type; | |||||
| for (nu = editnurb->first; nu; nu = nu->next) { | |||||
| if ((nu->type == CU_BEZIER) && (type == CU_BEZIER)) { | |||||
| ED_curve_select_all_bezt(nu); | |||||
| } | |||||
| else if ((nu->type == CU_NURBS) && (type == CU_NURBS)) { | |||||
| ED_curve_select_all_bp(nu); | |||||
| } | |||||
| else if ((nu->type == CU_POLY) && (type == CU_POLY)) { | |||||
| ED_curve_select_all_bp(nu); | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| static int curve_select_similar_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Object *obedit = CTX_data_edit_object(C); | |||||
| Curve *cu = obedit->data; | |||||
| ListBase *editnurb = object_editcurve_get(obedit); | |||||
| bool status = false; | |||||
| /* Get props */ | |||||
| const int type = RNA_enum_get(op->ptr, "type"); | |||||
| const float thresh = RNA_float_get(op->ptr, "threshold"); | |||||
| const float align = RNA_float_get(op->ptr, "alignment"); | |||||
| const int compare = RNA_enum_get(op->ptr, "compare"); | |||||
| switch (type) { | |||||
| case SIMCURHAND_WEIGHT: | |||||
| status = ED_curve_select_similar_weight(editnurb, cu, compare, thresh); | |||||
| break; | |||||
| case SIMCURHAND_TYPE: | |||||
| status = ED_curve_select_similar_type(editnurb, cu); | |||||
| break; | |||||
| case SIMCURHAND_DIRECTION: | |||||
| status = ED_curve_select_similar_direction(editnurb, cu, align); | |||||
| break; | |||||
| case SIMCURHAND_RADIUS: | |||||
| status = ED_curve_select_similar_radius(editnurb, cu, compare, thresh); | |||||
| break; | |||||
| /*case SIMCURHAND_TILT: | |||||
| status = ED_curve_select_similar_tilt(editnurb, cu, align); | |||||
| break;*/ | |||||
| } | |||||
| if (!status) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| void CURVE_OT_select_similar(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Select Similar"; | |||||
| ot->idname = "CURVE_OT_select_similar"; | |||||
| ot->description = "Select similar curve points by property types"; | |||||
| /* api callbacks */ | |||||
| ot->invoke = WM_menu_invoke; | |||||
| ot->exec = curve_select_similar_exec; | |||||
| ot->poll = ED_operator_editsurfcurve; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| /* properties */ | |||||
| ot->prop = RNA_def_enum(ot->srna, "type", curve_prop_similar_types, SIMCURHAND_WEIGHT, "Type", ""); | |||||
| RNA_def_enum(ot->srna, "compare", curve_prop_similar_compare_types, SIM_CMP_EQ, "Compare", "Use with radius & weight"); | |||||
| RNA_def_float(ot->srna, "threshold", 100.0, 0.0, FLT_MAX, "Threshold", "Use with radius & weight", 0.0, 100.0); | |||||
| RNA_def_float(ot->srna, "alignment", 0.0, 0.0, 1.0, "Alignment", "Use with direction & tilt", 0.0, 1.0); | |||||
| } | |||||
| /********************** add duplicate operator *********************/ | /********************** add duplicate operator *********************/ | ||||
| static int duplicate_exec(bContext *C, wmOperator *op) | static int duplicate_exec(bContext *C, wmOperator *op) | ||||
| Context not available. | |||||