Fix T64829: Active point of Curve objects is not displayed correctly
authorPhilipp Oeser <info@graphics-engineer.com>
Fri, 24 May 2019 10:10:27 +0000 (12:10 +0200)
committerPhilipp Oeser <info@graphics-engineer.com>
Tue, 28 May 2019 14:08:34 +0000 (16:08 +0200)
three issues here:
- when curves had multiple nurbs, the active vert is per nurb
[curve_create_edit_data_and_handles() wasnt taking that into account]
- code could go wrong when points where hidden
- upon selection, tag curve ID_RECALC_COPY_ON_WRITE for batch cache
update

Reviewers: brecht, fclem, sergey

Maniphest Tasks: T64829

Differential Revision: https://developer.blender.org/D4943

source/blender/draw/intern/draw_cache_impl_curve.c
source/blender/editors/curve/editcurve.c

index 663fbf6..00bbbab 100644 (file)
@@ -695,7 +695,8 @@ static char beztriple_vflag_get(
 {
   char vflag = 0;
   SET_FLAG_FROM_TEST(vflag, (flag & SELECT), VFLAG_VERT_SELECTED);
-  SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert), VFLAG_VERT_ACTIVE);
+  SET_FLAG_FROM_TEST(
+      vflag, (v_idx == rdata->actvert && nu_id == rdata->actnu), VFLAG_VERT_ACTIVE);
   SET_FLAG_FROM_TEST(vflag, (nu_id == rdata->actnu), ACTIVE_NURB);
   /* handle color id */
   vflag |= col_id << 4; /* << 4 because of EVEN_U_BIT */
@@ -706,7 +707,8 @@ static char bpoint_vflag_get(CurveRenderData *rdata, char flag, int v_idx, int n
 {
   char vflag = 0;
   SET_FLAG_FROM_TEST(vflag, (flag & SELECT), VFLAG_VERT_SELECTED);
-  SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert), VFLAG_VERT_ACTIVE);
+  SET_FLAG_FROM_TEST(
+      vflag, (v_idx == rdata->actvert && nu_id == rdata->actnu), VFLAG_VERT_ACTIVE);
   SET_FLAG_FROM_TEST(vflag, (nu_id == rdata->actnu), ACTIVE_NURB);
   SET_FLAG_FROM_TEST(vflag, ((u % 2) == 0), EVEN_U_BIT);
   vflag |= COLOR_NURB_ULINE_ID << 4; /* << 4 because of EVEN_U_BIT */
@@ -754,7 +756,7 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata,
     GPU_indexbuf_init(elbp_lines, GPU_PRIM_LINES, edges_len_capacity, verts_len_capacity);
   }
 
-  int v_idx = 0, nu_id = 0;
+  int nu_id = 0;
   for (Nurb *nu = rdata->nurbs->first; nu; nu = nu->next, nu_id++) {
     const BezTriple *bezt = nu->bezt;
     const BPoint *bp = nu->bp;
@@ -773,9 +775,9 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata,
         }
         if (vbo_data) {
           char vflag[3] = {
-              beztriple_vflag_get(rdata, bezt->f1, bezt->h1, v_idx, nu_id),
-              beztriple_vflag_get(rdata, bezt->f2, bezt->h1, v_idx, nu_id),
-              beztriple_vflag_get(rdata, bezt->f3, bezt->h2, v_idx, nu_id),
+              beztriple_vflag_get(rdata, bezt->f1, bezt->h1, a, nu_id),
+              beztriple_vflag_get(rdata, bezt->f2, bezt->h1, a, nu_id),
+              beztriple_vflag_get(rdata, bezt->f3, bezt->h2, a, nu_id),
           };
           for (int j = 0; j < 3; j++) {
             GPU_vertbuf_attr_set(vbo_data, attr_id.data, vbo_len_used + j, &vflag[j]);
@@ -787,7 +789,6 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata,
           }
         }
         vbo_len_used += 3;
-        v_idx += 1;
       }
     }
     else if (bp) {
@@ -814,14 +815,13 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata,
           }
         }
         if (vbo_data) {
-          char vflag = bpoint_vflag_get(rdata, bp->f1, v_idx, nu_id, u);
+          char vflag = bpoint_vflag_get(rdata, bp->f1, a, nu_id, u);
           GPU_vertbuf_attr_set(vbo_data, attr_id.data, vbo_len_used, &vflag);
         }
         if (vbo_pos) {
           GPU_vertbuf_attr_set(vbo_pos, attr_id.pos, vbo_len_used, bp->vec);
         }
         vbo_len_used += 1;
-        v_idx += 1;
       }
     }
   }
index 8d131ee..48094c7 100644 (file)
@@ -4895,7 +4895,7 @@ bool ED_curve_editnurb_select_pick(
 
         ED_curve_deselect_all(((Curve *)ob_iter->data)->editnurb);
 
-        DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
+        DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT | ID_RECALC_COPY_ON_WRITE);
         WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
       }
       MEM_freeN(objects);
@@ -5010,7 +5010,7 @@ bool ED_curve_editnurb_select_pick(
       ED_object_base_activate(C, basact);
     }
 
-    DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+    DEG_id_tag_update(obedit->data, ID_RECALC_SELECT | ID_RECALC_COPY_ON_WRITE);
     WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
 
     return true;