"Every Nth number of Points" operator for curves/surfaces
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 10 May 2010 17:32:11 +0000 (17:32 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 10 May 2010 17:32:11 +0000 (17:32 +0000)
This is replacement of old "Select every Nth" operator with
de-select strategy to make the same behaviour as for meshes.

release/scripts/ui/space_view3d.py
source/blender/editors/curve/curve_intern.h
source/blender/editors/curve/curve_ops.c
source/blender/editors/curve/editcurve.c
source/blender/editors/include/ED_curve.h

index a8fc4eb89af9e708d3fb04e75fe6c3f9bf0e223d..8be176843fc4b371da53a278e7e9d71d7a32f506 100644 (file)
@@ -523,7 +523,7 @@ class VIEW3D_MT_select_edit_curve(bpy.types.Menu):
         layout.operator("curve.select_all", text="Select/Deselect All")
         layout.operator("curve.select_inverse")
         layout.operator("curve.select_random")
-        layout.operator("curve.select_every_nth")
+        layout.operator("curve.select_nth", text="Every Nth Number of Points")
 
         layout.separator()
 
@@ -552,7 +552,7 @@ class VIEW3D_MT_select_edit_surface(bpy.types.Menu):
         layout.operator("curve.select_all", text="Select/Deselect All")
         layout.operator("curve.select_inverse")
         layout.operator("curve.select_random")
-        layout.operator("curve.select_every_nth")
+        layout.operator("curve.select_nth", text="Every Nth Number of Points")
 
         layout.separator()
 
index d3b377e2a677ab87a9bfc32f03dd5565df0c60c7..a9f9aac70d51cd3151772ad05e3f8792441a6cc7 100644 (file)
@@ -96,7 +96,7 @@ void CURVE_OT_select_previous(struct wmOperatorType *ot);
 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_every_nth(struct wmOperatorType *ot);
+void CURVE_OT_select_nth(struct wmOperatorType *ot);
 
 void CURVE_OT_switch_direction(struct wmOperatorType *ot);
 void CURVE_OT_subdivide(struct wmOperatorType *ot);
index e0340ce67c66acbcbb4128b49f9fbbaad3240c13..fa341ee19ef80cac9d9186c19652e8126d82c0ac 100644 (file)
@@ -111,7 +111,7 @@ void ED_operatortypes_curve(void)
        WM_operatortype_append(CURVE_OT_select_more);
        WM_operatortype_append(CURVE_OT_select_less);
        WM_operatortype_append(CURVE_OT_select_random);
-       WM_operatortype_append(CURVE_OT_select_every_nth);
+       WM_operatortype_append(CURVE_OT_select_nth);
 
        WM_operatortype_append(CURVE_OT_switch_direction);
        WM_operatortype_append(CURVE_OT_subdivide);
index 22976c7e5d6bae52967d424217f937d5f71e259f..5c64b82ec873450265db5ebd7f03b26d93c0591f 100644 (file)
@@ -4272,37 +4272,128 @@ void CURVE_OT_select_random(wmOperatorType *ot)
        RNA_def_boolean(ot->srna, "extend", FALSE, "Extend Selection", "Extend selection instead of deselecting everything first.");
 }
 
-/********************** select every nth *********************/
+/********************* every nth number of point *******************/
 
-static int select_every_nth_exec(bContext *C, wmOperator *op)
+static int point_on_nurb(Nurb *nu, void *point)
+{
+       if (nu->bezt) {
+               BezTriple *bezt= (BezTriple*)point;
+               return bezt >= nu->bezt && bezt < nu->bezt + nu->pntsu;
+       } else {
+               BPoint *bp= (BPoint*)point;
+               return bp >= nu->bp && bp < nu->bp + nu->pntsu * nu->pntsv;
+       }
+}
+
+static void select_nth_bezt(Nurb *nu, BezTriple *bezt, int nth)
+{
+       int a, start;
+
+       start= bezt - nu->bezt;
+       a= nu->pntsu;
+       bezt= nu->bezt + a - 1;
+
+       while (a--) {
+               if (abs(start - a) % nth) {
+                       select_beztriple(bezt, DESELECT, 1, HIDDEN);
+               }
+
+               bezt--;
+       }
+}
+
+static void select_nth_bp(Nurb *nu, BPoint *bp, int nth)
+{
+       int a, startrow, startpnt;
+       int dist, row, pnt;
+
+       startrow= (bp - nu->bp) / nu->pntsu;
+       startpnt= (bp - nu->bp) % nu->pntsu;
+
+       a= nu->pntsu * nu->pntsv;
+       bp= nu->bp + a - 1;
+       row = nu->pntsv - 1;
+       pnt = nu->pntsu - 1;
+
+       while (a--) {
+               dist= abs(pnt - startpnt) + abs(row - startrow);
+               if (dist % nth) {
+                       select_bpoint(bp, DESELECT, 1, HIDDEN);
+               }
+
+               pnt--;
+               if (pnt < 0) {
+                       pnt= nu->pntsu - 1;
+                       row--;
+               }
+
+               bp--;
+       }
+}
+
+int CU_select_nth(Object *obedit, int nth)
+{
+       Curve *cu= (Curve*)obedit->data;
+       ListBase *nubase= cu->editnurb;
+       Nurb *nu;
+       int ok=0;
+
+       /* Search nurb to which selected point belongs to */
+       nu= nubase->first;
+       while (nu) {
+               if (point_on_nurb(nu, cu->lastsel)) {
+                       ok= 1;
+                       break;
+               }
+               nu= nu->next;
+       }
+
+       if (!ok) return 0;
+
+       if (nu->bezt) {
+               select_nth_bezt(nu, cu->lastsel, nth);
+       } else {
+               select_nth_bp(nu, cu->lastsel, nth);
+       }
+
+       return 1;
+}
+
+static int select_nth_exec(bContext *C, wmOperator *op)
 {
        Object *obedit= CTX_data_edit_object(C);
-       ListBase *editnurb= curve_get_editcurve(obedit);
-       int n= RNA_int_get(op->ptr, "n");
-       
-       select_adjacent_cp(editnurb, n, 1, SELECT);
-       select_adjacent_cp(editnurb, -n, 1, SELECT);
-       
+       int nth= RNA_int_get(op->ptr, "nth");
+
+       if (!CU_select_nth(obedit, nth)) {
+               if (obedit->type == OB_SURF) {
+                       BKE_report(op->reports, RPT_ERROR, "Surface hasn't got active point");
+               } else {
+                       BKE_report(op->reports, RPT_ERROR, "Curve hasn't got active point");
+               }
+
+               return OPERATOR_CANCELLED;
+       }
+
        WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        return OPERATOR_FINISHED;
 }
 
-void CURVE_OT_select_every_nth(wmOperatorType *ot)
+void CURVE_OT_select_nth(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Select Every Nth";
-       ot->idname= "CURVE_OT_select_every_nth";
-       
+       ot->name= "Select Nth";
+       ot->description= "";
+       ot->idname= "CURVE_OT_select_nth";
+
        /* api callbacks */
-       ot->exec= select_every_nth_exec;
+       ot->exec= select_nth_exec;
        ot->poll= ED_operator_editsurfcurve;
-       
+
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
-       /* properties */
-       RNA_def_int(ot->srna, "n", 2, 2, INT_MAX, "N", "Select every Nth element", 2, 25);
+       RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX);
 }
 
 /********************** add duplicate operator *********************/
index 3710d4bc4cc9f08cd58ce37663cd5111b16a25b9..a229d919e776273dc2423efa02d021551f720901 100644 (file)
@@ -71,5 +71,7 @@ void  free_editText   (struct Object *obedit);
 
 void   ED_text_to_object(struct bContext *C, struct Text *text, int split_lines);
 
+int CU_select_nth(struct Object *obedit, int nth);
+
 #endif /* ED_CURVE_H */