Edit Surface: Use edit curve engine to display edit surface
authorClément Foucault <foucault.clem@gmail.com>
Wed, 26 Sep 2018 14:40:09 +0000 (16:40 +0200)
committerClément Foucault <foucault.clem@gmail.com>
Wed, 26 Sep 2018 14:42:57 +0000 (16:42 +0200)
It's so similar in practice that we don't need a separate engine for edit
surface overlays.

source/blender/draw/intern/draw_cache.c
source/blender/draw/intern/draw_cache_impl_curve.c
source/blender/draw/intern/draw_common.c
source/blender/draw/intern/draw_common.h
source/blender/draw/modes/draw_mode_engines.h
source/blender/draw/modes/edit_curve_mode.c
source/blender/draw/modes/shaders/common_globals_lib.glsl
source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl
source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl

index 9e6e50b..6376855 100644 (file)
@@ -3116,7 +3116,7 @@ GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob, float normal_size)
 
 GPUBatch *DRW_cache_curve_edge_overlay_get(Object *ob)
 {
-       BLI_assert(ob->type == OB_CURVE);
+       BLI_assert(ELEM(ob->type, OB_CURVE, OB_SURF));
 
        struct Curve *cu = ob->data;
        return DRW_curve_batch_cache_get_overlay_edges(cu);
@@ -3124,7 +3124,7 @@ GPUBatch *DRW_cache_curve_edge_overlay_get(Object *ob)
 
 GPUBatch *DRW_cache_curve_vert_overlay_get(Object *ob, bool handles)
 {
-       BLI_assert(ob->type == OB_CURVE);
+       BLI_assert(ELEM(ob->type, OB_CURVE, OB_SURF));
 
        struct Curve *cu = ob->data;
        return DRW_curve_batch_cache_get_overlay_verts(cu, handles);
index 0f06f36..4702319 100644 (file)
@@ -46,6 +46,7 @@
 
 #define SELECT            1
 #define ACTIVE_NURB       1 << 2
+#define EVEN_U_BIT        1 << 3 /* Alternate this bit for every U vert. */
 
 /* Used as values of `color_id` in `edit_curve_overlay_handle_geom.glsl` */
 enum {
@@ -79,9 +80,10 @@ static void curve_render_overlay_verts_edges_len_get(
                        edge_len += 2 * nu->pntsu;
                }
                else if (nu->bp) {
-                       vert_len += nu->pntsu;
+                       vert_len += nu->pntsu * nu->pntsv;
                        /* segments between points */
-                       edge_len += nu->pntsu - 1;
+                       edge_len += (nu->pntsu - 1) * nu->pntsv;
+                       edge_len += (nu->pntsv - 1) * nu->pntsu;
                }
        }
        if (r_vert_len) {
@@ -169,9 +171,6 @@ typedef struct CurveRenderData {
                EditFont *edit_font;
        } text;
 
-       bool hide_handles;
-       bool hide_normals;
-
        /* borrow from 'Object' */
        CurveCache *ob_curve_cache;
 
@@ -206,10 +205,6 @@ static CurveRenderData *curve_render_data_create(Curve *cu, CurveCache *ob_curve
        rdata->types = types;
        ListBase *nurbs;
 
-       /* TODO(fclem): hide them in the shader/draw engine */
-       rdata->hide_handles = false;
-       rdata->hide_normals = false;
-
        rdata->actnu = cu->actnu;
        rdata->actvert = cu->actvert;
 
@@ -537,14 +532,6 @@ static GPUIndexBuf *curve_batch_cache_get_wire_edges(CurveRenderData *rdata, Cur
                                }
                        }
                }
-
-               if (rdata->hide_handles) {
-                       BLI_assert(edge_len_used <= edge_len);
-               }
-               else {
-                       BLI_assert(edge_len_used == edge_len);
-               }
-
                cache->wire.elem = GPU_indexbuf_build(&elb);
        }
 
@@ -680,7 +667,7 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu)
                                                        vflag |= (is_active_nurb) ? ACTIVE_NURB : 0;
                                                        /* handle color id */
                                                        char col_id = (&bezt->h1)[j / 2];
-                                                       vflag |= col_id << 3; /* << 3 because of ACTIVE_NURB */
+                                                       vflag |= col_id << 4; /* << 4 because of EVEN_U_BIT */
                                                        GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[j]);
                                                        GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag);
                                                        vbo_len_used += 1;
@@ -691,13 +678,15 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu)
                        }
                        else if (nu->bp) {
                                int a = 0;
-                               for (const BPoint *bp = nu->bp; a < nu->pntsu; a++, bp++) {
+                               int pt_len = nu->pntsu * nu->pntsv;
+                               for (const BPoint *bp = nu->bp; a < pt_len; a++, bp++) {
                                        if (bp->hide == false) {
                                                const bool is_active = (i == rdata->actvert);
                                                char vflag = (bp->f1 & SELECT) ? VFLAG_VERTEX_SELECTED : 0;
                                                vflag |= (is_active) ? VFLAG_VERTEX_ACTIVE : 0;
                                                vflag |= (is_active_nurb) ? ACTIVE_NURB : 0;
-                                               vflag |= COLOR_NURB_ULINE_ID << 3; /* << 3 because of ACTIVE_NURB */
+                                               vflag |= (((a % nu->pntsu) % 2) == 0) ? EVEN_U_BIT : 0;
+                                               vflag |= COLOR_NURB_ULINE_ID << 4; /* << 4 because of EVEN_U_BIT */
                                                GPU_indexbuf_add_point_vert(&elb, vbo_len_used);
                                                GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bp->vec);
                                                GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag);
@@ -718,7 +707,6 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu)
                cache->overlay.verts_no_handles = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, ibo, GPU_BATCH_OWNS_INDEX);
        }
 
-
        if (cache->overlay.edges == NULL) {
                GPUVertBuf *vbo = cache->overlay.verts->verts[0];
 
@@ -742,15 +730,31 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu)
                                }
                        }
                        else if (nu->bp) {
-                               curr_index += 1;
-                               int a = 1;
-                               for (const BPoint *bp_prev = nu->bp, *bp_curr = &nu->bp[1]; a < nu->pntsu; a++, bp_prev = bp_curr++) {
-                                       if (bp_prev->hide == false) {
-                                               if (bp_curr->hide == false) {
-                                                       GPU_indexbuf_add_line_verts(&elb, curr_index - 1, curr_index + 0);
+                               int a = 0;
+                               int next_v_index = curr_index;
+                               for (const BPoint *bp = nu->bp; a < nu->pntsu; a++, bp++) {
+                                       if (bp->hide == false) {
+                                               next_v_index += 1;
+                                       }
+                               }
+
+                               int pt_len = nu->pntsu * nu->pntsv;
+                               for (a = 0; a < pt_len; a++) {
+                                       const BPoint *bp_curr = &nu->bp[a];
+                                       const BPoint *bp_next_u = ((a % nu->pntsu) < (nu->pntsu - 1)) ? &nu->bp[a + 1] : NULL;
+                                       const BPoint *bp_next_v = (a < (pt_len - nu->pntsu)) ? &nu->bp[a + nu->pntsu] : NULL;
+                                       if (bp_curr->hide == false) {
+                                               if (bp_next_u && (bp_next_u->hide == false)) {
+                                                       GPU_indexbuf_add_line_verts(&elb, curr_index, curr_index + 1);
+                                               }
+                                               if (bp_next_v && (bp_next_v->hide == false)) {
+                                                       GPU_indexbuf_add_line_verts(&elb, curr_index, next_v_index);
                                                }
                                                curr_index += 1;
                                        }
+                                       if (bp_next_v && (bp_next_v->hide == false)) {
+                                               next_v_index += 1;
+                                       }
                                }
                        }
                }
index 876f440..eeaa204 100644 (file)
@@ -99,7 +99,9 @@ void DRW_globals_update(void)
        UI_GetThemeColor4fv(TH_HANDLE_SEL_ALIGN, ts.colorHandleSelAlign);
        UI_GetThemeColor4fv(TH_HANDLE_SEL_AUTOCLAMP, ts.colorHandleSelAutoclamp);
        UI_GetThemeColor4fv(TH_NURB_ULINE, ts.colorNurbUline);
+       UI_GetThemeColor4fv(TH_NURB_VLINE, ts.colorNurbVline);
        UI_GetThemeColor4fv(TH_NURB_SEL_ULINE, ts.colorNurbSelUline);
+       UI_GetThemeColor4fv(TH_NURB_SEL_VLINE, ts.colorNurbSelVline);
        UI_GetThemeColor4fv(TH_ACTIVE_SPLINE, ts.colorActiveSpline);
 
        UI_GetThemeColor4fv(TH_BONE_POSE, ts.colorBonePose);
index ceeefdd..2640451 100644 (file)
@@ -90,7 +90,9 @@ typedef struct GlobalsUboStorage {
        float colorHandleSelAlign[4];
        float colorHandleSelAutoclamp[4];
        float colorNurbUline[4];
+       float colorNurbVline[4];
        float colorNurbSelUline[4];
+       float colorNurbSelVline[4];
        float colorActiveSpline[4];
 
        float colorBonePose[4];
index 8e8ddfe..0597243 100644 (file)
@@ -32,7 +32,6 @@ extern DrawEngineType draw_engine_edit_curve_type;
 extern DrawEngineType draw_engine_edit_lattice_type;
 extern DrawEngineType draw_engine_edit_mesh_type;
 extern DrawEngineType draw_engine_edit_metaball_type;
-extern DrawEngineType draw_engine_edit_surface_type;
 extern DrawEngineType draw_engine_edit_text_type;
 extern DrawEngineType draw_engine_motion_path_type;
 extern DrawEngineType draw_engine_paint_texture_type;
index 9dc6161..8f61c8d 100644 (file)
@@ -241,12 +241,7 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob)
        UNUSED_VARS(psl, stl);
 
        if (ob->type == OB_CURVE) {
-#if 0
-               if (ob == draw_ctx->object_edit)
-#else
-               if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob))
-#endif
-               {
+               if (BKE_object_is_in_editmode(ob)) {
                        Curve *cu = ob->data;
                        /* Get geometry cache */
                        struct GPUBatch *geom;
@@ -268,16 +263,16 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob)
                        DRW_shgroup_call_add(stl->g_data->overlay_vert_shgrp, geom, ob->obmat);
                }
        }
-}
 
-/* Optional: Post-cache_populate callback */
-static void EDIT_CURVE_cache_finish(void *vedata)
-{
-       EDIT_CURVE_PassList *psl = ((EDIT_CURVE_Data *)vedata)->psl;
-       EDIT_CURVE_StorageList *stl = ((EDIT_CURVE_Data *)vedata)->stl;
+       if (ob->type == OB_SURF) {
+               if (BKE_object_is_in_editmode(ob)) {
+                       struct GPUBatch *geom = DRW_cache_curve_edge_overlay_get(ob);
+                       DRW_shgroup_call_add(stl->g_data->overlay_edge_shgrp, geom, ob->obmat);
 
-       /* Do something here! dependent on the objects gathered */
-       UNUSED_VARS(psl, stl);
+                       geom = DRW_cache_curve_vert_overlay_get(ob, false);
+                       DRW_shgroup_call_add(stl->g_data->overlay_vert_shgrp, geom, ob->obmat);
+               }
+       }
 }
 
 /* Draw time ! Control rendering pipeline from here */
@@ -325,7 +320,7 @@ DrawEngineType draw_engine_edit_curve_type = {
        &EDIT_CURVE_engine_free,
        &EDIT_CURVE_cache_init,
        &EDIT_CURVE_cache_populate,
-       &EDIT_CURVE_cache_finish,
+       NULL,
        NULL, /* draw_background but not needed by mode engines */
        &EDIT_CURVE_draw_scene,
        NULL,
index c024383..bf761cd 100644 (file)
@@ -46,7 +46,9 @@ layout(std140) uniform globalsBlock {
        vec4 colorHandleSelAlign;
        vec4 colorHandleSelAutoclamp;
        vec4 colorNurbUline;
+       vec4 colorNurbVline;
        vec4 colorNurbSelUline;
+       vec4 colorNurbSelVline;
        vec4 colorActiveSpline;
 
        vec4 colorBonePose;
index f284a34..7bc9b38 100644 (file)
@@ -2,12 +2,13 @@
 #define VERTEX_ACTIVE   1 << 0
 #define VERTEX_SELECTED 1 << 1
 #define ACTIVE_NURB     1 << 2 /* Keep the same value of `ACTIVE_NURB` in `draw_cache_imp_curve.c` */
-#define NURBS_EDGE_SELECTED (((vertFlag[1] & vertFlag[0]) & VERTEX_SELECTED) != 0)
+#define EVEN_U_BIT      1 << 3
 
 layout(lines) in;
 layout(triangle_strip, max_vertices = 10) out;
 
 uniform vec2 viewportSize;
+uniform bool showCurveHandles;
 
 flat in int vertFlag[];
 
@@ -28,13 +29,11 @@ void output_line(vec2 offset, vec4 color)
 
 void main()
 {
-       /* TODO: vertex size */
-
        vec4 v1 = gl_in[0].gl_Position;
        vec4 v2 = gl_in[1].gl_Position;
 
        int is_active_nurb = (vertFlag[1] & ACTIVE_NURB);
-       int color_id = (vertFlag[1] >> 3);
+       int color_id = (vertFlag[1] >> 4);
 
        /* Don't output any edges if we don't show handles */
        if (!showCurveHandles && (color_id < 5))
@@ -48,7 +47,16 @@ void main()
        else if (color_id == 2) inner_color = (edge_selected) ? colorHandleSelVect : colorHandleVect;
        else if (color_id == 3) inner_color = (edge_selected) ? colorHandleSelAlign : colorHandleAlign;
        else if (color_id == 4) inner_color = (edge_selected) ? colorHandleSelAutoclamp : colorHandleAutoclamp;
-       else                    inner_color = (NURBS_EDGE_SELECTED) ? colorNurbSelUline : colorNurbUline;
+       else {
+               bool is_selected = (((vertFlag[1] & vertFlag[0]) & VERTEX_SELECTED) != 0);
+               bool is_u_segment = (((vertFlag[1] ^ vertFlag[0]) & EVEN_U_BIT) != 0);
+               if (is_u_segment) {
+                       inner_color = (is_selected) ? colorNurbSelUline : colorNurbUline;
+               }
+               else {
+                       inner_color = (is_selected) ? colorNurbSelVline : colorNurbVline;
+               }
+       }
 
        vec4 outer_color = (is_active_nurb != 0)
                           ? mix(colorActiveSpline, inner_color, 0.25) /* Minimize active color bleeding on inner_color. */
index 44d1560..85e38ba 100644 (file)
@@ -14,11 +14,13 @@ out vec4 finalColor;
 
 void main()
 {
-       if ((data & VERTEX_ACTIVE) != 0) {
-               finalColor = colorEditMeshActive;
-       }
        if ((data & VERTEX_SELECTED) != 0) {
-               finalColor = colorVertexSelect;
+               if ((data & VERTEX_ACTIVE) != 0) {
+                       finalColor = colorEditMeshActive;
+               }
+               else {
+                       finalColor = colorVertexSelect;
+               }
        }
        else {
                finalColor = colorVertex;