forked from bartvdbraak/blender
Select Similar for edit-curve
D1381 by @johnroper100 with edits
This commit is contained in:
parent
161bbfcd19
commit
ec64bf17e3
@ -730,6 +730,7 @@ class VIEW3D_MT_select_edit_curve(Menu):
|
||||
layout.operator("curve.select_random")
|
||||
layout.operator("curve.select_nth")
|
||||
layout.operator("curve.select_linked", text="Select Linked")
|
||||
layout.operator("curve.select_similar", text="Select Similar")
|
||||
|
||||
layout.separator()
|
||||
|
||||
@ -760,6 +761,7 @@ class VIEW3D_MT_select_edit_surface(Menu):
|
||||
layout.operator("curve.select_random")
|
||||
layout.operator("curve.select_nth")
|
||||
layout.operator("curve.select_linked", text="Select Linked")
|
||||
layout.operator("curve.select_similar", text="Select Similar")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -150,6 +150,7 @@ void CURVE_OT_select_more(struct wmOperatorType *ot);
|
||||
void CURVE_OT_select_less(struct wmOperatorType *ot);
|
||||
void CURVE_OT_select_random(struct wmOperatorType *ot);
|
||||
void CURVE_OT_select_nth(struct wmOperatorType *ot);
|
||||
void CURVE_OT_select_similar(struct wmOperatorType *ot);
|
||||
|
||||
/* editcurve_add.c */
|
||||
void CURVE_OT_primitive_bezier_curve_add(struct wmOperatorType *ot);
|
||||
|
@ -128,6 +128,7 @@ void ED_operatortypes_curve(void)
|
||||
WM_operatortype_append(CURVE_OT_select_less);
|
||||
WM_operatortype_append(CURVE_OT_select_random);
|
||||
WM_operatortype_append(CURVE_OT_select_nth);
|
||||
WM_operatortype_append(CURVE_OT_select_similar);
|
||||
|
||||
WM_operatortype_append(CURVE_OT_switch_direction);
|
||||
WM_operatortype_append(CURVE_OT_subdivide);
|
||||
@ -241,6 +242,7 @@ void ED_keymap_curve(wmKeyConfig *keyconf)
|
||||
WM_keymap_add_item(keymap, "CURVE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "CURVE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "CURVE_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "CURVE_OT_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
|
||||
kmi = WM_keymap_add_item(keymap, "CURVE_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0);
|
||||
RNA_boolean_set(kmi->ptr, "deselect", false);
|
||||
|
@ -20,7 +20,7 @@
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
* Contributor(s): John Roper
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
@ -1154,3 +1154,347 @@ void CURVE_OT_select_nth(wmOperatorType *ot)
|
||||
RNA_def_int(ot->srna, "skip", 1, 1, INT_MAX, "Skip", "", 1, 100);
|
||||
RNA_def_int(ot->srna, "offset", 0, INT_MIN, INT_MAX, "Offset", "", -100, 100);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Select Similar */
|
||||
|
||||
/** \name Select Similar
|
||||
* \{ */
|
||||
|
||||
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_TYPE = 0,
|
||||
SIMCURHAND_RADIUS,
|
||||
SIMCURHAND_WEIGHT,
|
||||
SIMCURHAND_DIRECTION,
|
||||
};
|
||||
|
||||
static EnumPropertyItem curve_prop_similar_types[] = {
|
||||
{SIMCURHAND_TYPE, "TYPE", 0, "Type", ""},
|
||||
{SIMCURHAND_RADIUS, "RADIUS", 0, "Radius", ""},
|
||||
{SIMCURHAND_WEIGHT, "WEIGHT", 0, "Weight", ""},
|
||||
{SIMCURHAND_DIRECTION, "DIRECTION", 0, "Direction", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static int curve_select_similar_cmp_fl(const float delta, const float thresh, const int compare)
|
||||
{
|
||||
switch (compare) {
|
||||
case SIM_CMP_EQ:
|
||||
return (fabsf(delta) <= thresh);
|
||||
case SIM_CMP_GT:
|
||||
return ((delta + thresh) >= 0.0f);
|
||||
case SIM_CMP_LT:
|
||||
return ((delta - thresh) <= 0.0f);
|
||||
default:
|
||||
BLI_assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void curve_select_similar_direction__bezt(Nurb *nu, const float dir_ref[3], float angle_cos)
|
||||
{
|
||||
BezTriple *bezt;
|
||||
int i;
|
||||
|
||||
for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
|
||||
if (!bezt->hide) {
|
||||
float dir[3];
|
||||
BKE_nurb_bezt_calc_normal(nu, bezt, dir);
|
||||
if (fabsf(dot_v3v3(dir_ref, dir)) >= angle_cos) {
|
||||
select_beztriple(bezt, SELECT, SELECT, VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void curve_select_similar_direction__bp(Nurb *nu, const float dir_ref[3], float angle_cos)
|
||||
{
|
||||
BPoint *bp;
|
||||
int i;
|
||||
|
||||
for (i = nu->pntsu, bp = nu->bp; i--; bp++) {
|
||||
if (!bp->hide) {
|
||||
float dir[3];
|
||||
BKE_nurb_bpoint_calc_normal(nu, bp, dir);
|
||||
if (fabsf(dot_v3v3(dir_ref, dir)) >= angle_cos) {
|
||||
select_bpoint(bp, SELECT, SELECT, VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool curve_select_similar_direction(ListBase *editnurb, Curve *cu, float thresh)
|
||||
{
|
||||
Nurb *nu, *act_nu;
|
||||
void *act_vert;
|
||||
float dir[3];
|
||||
float angle_cos;
|
||||
|
||||
if (!BKE_curve_nurb_vert_active_get(cu, &act_nu, &act_vert)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (act_nu->type == CU_BEZIER) {
|
||||
BKE_nurb_bezt_calc_normal(act_nu, act_vert, dir);
|
||||
}
|
||||
else {
|
||||
BKE_nurb_bpoint_calc_normal(act_nu, act_vert, dir);
|
||||
}
|
||||
|
||||
/* map 0-1 to radians, 'cos' for comparison */
|
||||
angle_cos = cosf(thresh * M_PI_2);
|
||||
|
||||
for (nu = editnurb->first; nu; nu = nu->next) {
|
||||
if (nu->type == CU_BEZIER) {
|
||||
curve_select_similar_direction__bezt(nu, dir, angle_cos);
|
||||
}
|
||||
else {
|
||||
curve_select_similar_direction__bp(nu, dir, angle_cos);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void curve_select_similar_radius__bezt(Nurb *nu, float radius_ref, int compare, float thresh)
|
||||
{
|
||||
BezTriple *bezt;
|
||||
int i;
|
||||
|
||||
for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
|
||||
if (!bezt->hide) {
|
||||
if (curve_select_similar_cmp_fl(bezt->radius - radius_ref, thresh, compare)) {
|
||||
select_beztriple(bezt, SELECT, SELECT, VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void curve_select_similar_radius__bp(Nurb *nu, float radius_ref, int compare, float thresh)
|
||||
{
|
||||
BPoint *bp;
|
||||
int i;
|
||||
|
||||
for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
|
||||
if (!bp->hide) {
|
||||
if (curve_select_similar_cmp_fl(bp->radius - radius_ref, thresh, compare)) {
|
||||
select_bpoint(bp, SELECT, SELECT, VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool curve_select_similar_radius(ListBase *editnurb, Curve *cu, float compare, float thresh)
|
||||
{
|
||||
Nurb *nu, *act_nu;
|
||||
void *act_vert;
|
||||
float radius_ref;
|
||||
|
||||
if (!BKE_curve_nurb_vert_active_get(cu, &act_nu, &act_vert)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (act_nu->type == CU_BEZIER) {
|
||||
radius_ref = ((BezTriple *)act_vert)->radius;
|
||||
}
|
||||
else {
|
||||
radius_ref = ((BPoint *)act_vert)->radius;
|
||||
}
|
||||
|
||||
/* make relative */
|
||||
thresh *= radius_ref;
|
||||
|
||||
for (nu = editnurb->first; nu; nu = nu->next) {
|
||||
if (nu->type == CU_BEZIER) {
|
||||
curve_select_similar_radius__bezt(nu, radius_ref, compare, thresh);
|
||||
}
|
||||
else {
|
||||
curve_select_similar_radius__bp(nu, radius_ref, compare, thresh);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void curve_select_similar_weight__bezt(Nurb *nu, float weight_ref, int compare, float thresh)
|
||||
{
|
||||
BezTriple *bezt;
|
||||
int i;
|
||||
|
||||
for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
|
||||
if (!bezt->hide) {
|
||||
if (curve_select_similar_cmp_fl(bezt->weight - weight_ref, thresh, compare)) {
|
||||
select_beztriple(bezt, SELECT, SELECT, VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void curve_select_similar_weight__bp(Nurb *nu, float weight_ref, int compare, float thresh)
|
||||
{
|
||||
BPoint *bp;
|
||||
int i;
|
||||
|
||||
for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
|
||||
if (!bp->hide) {
|
||||
if (curve_select_similar_cmp_fl(bp->weight - weight_ref, thresh, compare)) {
|
||||
select_bpoint(bp, SELECT, SELECT, VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool curve_select_similar_weight(ListBase *editnurb, Curve *cu, float compare, float thresh)
|
||||
{
|
||||
Nurb *nu, *act_nu;
|
||||
void *act_vert;
|
||||
float weight_ref;
|
||||
|
||||
if (!BKE_curve_nurb_vert_active_get(cu, &act_nu, &act_vert))
|
||||
return false;
|
||||
|
||||
if (act_nu->type == CU_BEZIER) {
|
||||
weight_ref = ((BezTriple *)act_vert)->weight;
|
||||
}
|
||||
else {
|
||||
weight_ref = ((BPoint *)act_vert)->weight;
|
||||
}
|
||||
|
||||
for (nu = editnurb->first; nu; nu = nu->next) {
|
||||
if (nu->type == CU_BEZIER) {
|
||||
curve_select_similar_weight__bezt(nu, weight_ref, compare, thresh);
|
||||
}
|
||||
else {
|
||||
curve_select_similar_weight__bp(nu, weight_ref, compare, thresh);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void curve_select_all__bezt(Nurb *nu)
|
||||
{
|
||||
BezTriple *bezt;
|
||||
int i;
|
||||
|
||||
for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
|
||||
if (!bezt->hide) {
|
||||
select_beztriple(bezt, SELECT, SELECT, VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void curve_select_all__bp(Nurb *nu)
|
||||
{
|
||||
BPoint *bp;
|
||||
int i;
|
||||
|
||||
for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
|
||||
if (!bp->hide) {
|
||||
select_bpoint(bp, SELECT, SELECT, VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool curve_select_similar_type(ListBase *editnurb, Curve *cu)
|
||||
{
|
||||
Nurb *nu, *act_nu;
|
||||
int type_ref;
|
||||
|
||||
/* Get active nurb type */
|
||||
act_nu = BKE_curve_nurb_active_get(cu);
|
||||
|
||||
if (!act_nu)
|
||||
return false;
|
||||
|
||||
/* Get the active nurb type */
|
||||
type_ref = act_nu->type;
|
||||
|
||||
for (nu = editnurb->first; nu; nu = nu->next) {
|
||||
if (nu->type == type_ref) {
|
||||
if (type_ref == CU_BEZIER) {
|
||||
curve_select_all__bezt(nu);
|
||||
}
|
||||
else {
|
||||
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 changed = false;
|
||||
|
||||
/* Get props */
|
||||
const int type = RNA_enum_get(op->ptr, "type");
|
||||
const float thresh = RNA_float_get(op->ptr, "threshold");
|
||||
const int compare = RNA_enum_get(op->ptr, "compare");
|
||||
|
||||
switch (type) {
|
||||
case SIMCURHAND_TYPE:
|
||||
changed = curve_select_similar_type(editnurb, cu);
|
||||
break;
|
||||
case SIMCURHAND_RADIUS:
|
||||
changed = curve_select_similar_radius(editnurb, cu, compare, thresh);
|
||||
break;
|
||||
case SIMCURHAND_WEIGHT:
|
||||
changed = curve_select_similar_weight(editnurb, cu, compare, thresh);
|
||||
break;
|
||||
case SIMCURHAND_DIRECTION:
|
||||
changed = curve_select_similar_direction(editnurb, cu, thresh);
|
||||
break;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
else {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
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 type";
|
||||
|
||||
/* 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", "");
|
||||
RNA_def_float(ot->srna, "threshold", 0.1, 0.0, FLT_MAX, "Threshold", "", 0.0, 100.0);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
Loading…
Reference in New Issue
Block a user