[Bf-blender-cvs] [1a3e4e4cc2b] temp-gpencil-masking: Basic structure to Mask Intersect

Antonio Vazquez noreply at git.blender.org
Tue Apr 20 16:39:56 CEST 2021


Commit: 1a3e4e4cc2b60700c764de22ef8a552f38c69a84
Author: Antonio Vazquez
Date:   Tue Apr 20 16:38:44 2021 +0200
Branches: temp-gpencil-masking
https://developer.blender.org/rB1a3e4e4cc2b60700c764de22ef8a552f38c69a84

Basic structure to Mask Intersect

WIP (still not working)

===================================================================

M	release/scripts/startup/bl_ui/properties_grease_pencil_common.py
M	source/blender/draw/engines/gpencil/gpencil_cache_utils.c
M	source/blender/draw/engines/gpencil/gpencil_engine.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/makesdna/DNA_gpencil_types.h
M	source/blender/makesrna/intern/rna_gpencil.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index 3064b33c7f7..16fd28551da 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -769,6 +769,7 @@ class GPENCIL_UL_masks(UIList):
         if self.layout_type in {'DEFAULT', 'COMPACT'}:
             row = layout.row(align=True)
             row.prop(mask, "name", text="", emboss=False, icon_value=icon)
+            row.prop(mask, "intersect", text="", emboss=False)
             row.prop(mask, "invert", text="", emboss=False)
             row.prop(mask, "hide", text="", emboss=False)
         elif self.layout_type == 'GRID':
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index ee51b751187..121c95e95f6 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -276,9 +276,9 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
   bool is_masked = (gpl->flag & GP_LAYER_USE_MASK) && !BLI_listbase_is_empty(&gpl->mask_layers);
 
   float vert_col_opacity = (override_vertcol) ?
-                               (is_vert_col_mode ? pd->vertex_paint_opacity : 0.0f) :
-                               pd->is_render ? gpl->vertex_paint_opacity :
-                                               pd->vertex_paint_opacity;
+                                           (is_vert_col_mode ? pd->vertex_paint_opacity : 0.0f) :
+                           pd->is_render ? gpl->vertex_paint_opacity :
+                                           pd->vertex_paint_opacity;
   /* Negate thickness sign to tag that strokes are in screen space.
    * Convert to world units (by default, 1 meter = 2000 px). */
   float thickness_scale = (is_screenspace) ? -1.0f : (gpd->pixfactor / GPENCIL_PIXEL_FACTOR);
@@ -293,6 +293,7 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
   tgp_layer->layer_id = BLI_findindex(&gpd->layers, gpl);
   tgp_layer->mask_bits = NULL;
   tgp_layer->mask_invert_bits = NULL;
+  tgp_layer->mask_union_bits = NULL;
   tgp_layer->blend_ps = NULL;
 
   /* Masking: Go through mask list and extract valid masks in a bitmap. */
@@ -302,6 +303,7 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
      * TODO(fclem): Find a better system without any limitation. */
     tgp_layer->mask_bits = BLI_memblock_alloc(pd->gp_maskbit_pool);
     tgp_layer->mask_invert_bits = BLI_memblock_alloc(pd->gp_maskbit_pool);
+    tgp_layer->mask_union_bits = BLI_memblock_alloc(pd->gp_maskbit_pool);
     BLI_bitmap_set_all(tgp_layer->mask_bits, false, GP_MAX_MASKBITS);
 
     LISTBASE_FOREACH (bGPDlayer_Mask *, mask, &gpl->mask_layers) {
@@ -311,8 +313,10 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
         int index = BLI_findindex(&gpd->layers, gpl_mask);
         if (index < GP_MAX_MASKBITS) {
           const bool invert = (mask->flag & GP_MASK_INVERT) != 0;
+          const bool intersect = (mask->flag & GP_MASK_INTERSECT) != 0;
           BLI_BITMAP_SET(tgp_layer->mask_bits, index, true);
           BLI_BITMAP_SET(tgp_layer->mask_invert_bits, index, invert);
+          BLI_BITMAP_SET(tgp_layer->mask_union_bits, index, intersect);
           valid_mask = true;
         }
       }
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 8bb336ebc96..ccb51ce0706 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -308,7 +308,15 @@ void GPENCIL_cache_init(void *ved)
     grp = DRW_shgroup_create(sh, psl->mask_invert_ps);
     DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
   }
+  {
+    // TODO: Fix pass creation
+    DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_LOGIC_INVERT;
+    DRW_PASS_CREATE(psl->mask_intersect_ps, state);
 
+    GPUShader *sh = GPENCIL_shader_mask_invert_get();
+    grp = DRW_shgroup_create(sh, psl->mask_intersect_ps);
+    DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+  }
   Camera *cam = (pd->camera != NULL) ? pd->camera->data : NULL;
 
   /* Pseudo DOF setup. */
@@ -752,6 +760,15 @@ void GPENCIL_cache_finish(void *ved)
                                         GPU_ATTACHMENT_TEXTURE(color_tx),
                                         GPU_ATTACHMENT_TEXTURE(pd->mask_tx),
                                     });
+
+      pd->mask_intersect_tx = DRW_texture_pool_query_2d(
+          size[0], size[1], mask_format, &draw_engine_gpencil_type);
+      GPU_framebuffer_ensure_config(&fbl->mask_intersect_fb,
+                                    {
+                                        GPU_ATTACHMENT_TEXTURE(depth_tx),
+                                        GPU_ATTACHMENT_TEXTURE(color_tx),
+                                        GPU_ATTACHMENT_TEXTURE(pd->mask_intersect_tx),
+                                    });
     }
 
     GPENCIL_antialiasing_init(vedata);
@@ -818,10 +835,23 @@ static void gpencil_draw_mask(GPENCIL_Data *vedata, GPENCIL_tObject *ob, GPENCIL
       GPU_framebuffer_clear_color_depth(fbl->mask_fb, clear_col, clear_depth);
     }
 
+    if (!BLI_BITMAP_TEST_BOOL(layer->mask_union_bits, i)) {
+      /* mask_intersect_fb is the same as mask_fb it can even reuse the same color & depth
+      texture.
+       * But it needs a dedicated mask_tx (named mask_intersect_tx). */
+      GPU_framebuffer_bind(fbl->mask_intersect_fb);
+      GPU_framebuffer_clear_color(fbl->mask_intersect_fb, clear_col);
+    }
+
     GPENCIL_tLayer *mask_layer = gpencil_layer_cache_get(ob, i);
     BLI_assert(mask_layer);
 
     DRW_draw_pass(mask_layer->geom_ps);
+
+    if (!BLI_BITMAP_TEST_BOOL(layer->mask_union_bits, i)) {
+      /* Fullscreen quad outputing. 1.0 - mask_intersect_tx in multiply blend mode. */
+      DRW_draw_pass(psl->mask_intersect_ps);
+    }
   }
 
   if (!inverted) {
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 5ceb909bc88..5404db31d7a 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -167,6 +167,7 @@ typedef struct GPENCIL_tLayer {
   /** Layer id of the mask. */
   BLI_bitmap *mask_bits;
   BLI_bitmap *mask_invert_bits;
+  BLI_bitmap *mask_union_bits;
   /** Index in the layer list. Used as id for masking. */
   int layer_id;
 } GPENCIL_tLayer;
@@ -211,6 +212,8 @@ typedef struct GPENCIL_PassList {
   struct DRWPass *merge_depth_ps;
   /* Invert mask buffer content. */
   struct DRWPass *mask_invert_ps;
+  /* Intersect mask buffer content. */
+  struct DRWPass *mask_intersect_ps;
   /* Anti-Aliasing. */
   struct DRWPass *smaa_edge_ps;
   struct DRWPass *smaa_weight_ps;
@@ -224,6 +227,7 @@ typedef struct GPENCIL_FramebufferList {
   struct GPUFrameBuffer *layer_fb;
   struct GPUFrameBuffer *object_fb;
   struct GPUFrameBuffer *mask_fb;
+  struct GPUFrameBuffer *mask_intersect_fb;
   struct GPUFrameBuffer *smaa_edge_fb;
   struct GPUFrameBuffer *smaa_weight_fb;
 } GPENCIL_FramebufferList;
@@ -283,6 +287,7 @@ typedef struct GPENCIL_PrivateData {
   GPUTexture *reveal_object_tx;
   /* Mask texture */
   GPUTexture *mask_tx;
+  GPUTexture *mask_intersect_tx;
   /* Anti-Aliasing. */
   GPUTexture *smaa_edge_tx;
   GPUTexture *smaa_weight_tx;
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 8facdca2f9c..5936490c0e4 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -436,6 +436,8 @@ typedef enum ebGPDlayer_Mask_Flag {
   GP_MASK_HIDE = (1 << 0),
   /* Mask is inverted. */
   GP_MASK_INVERT = (1 << 1),
+  /* Mask is intersecting. */
+  GP_MASK_INTERSECT = (1 << 2),
 } ebGPDlayer_Mask_Flag;
 
 /* Runtime temp data for bGPDlayer */
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 1fbbffa99d5..4b2a117e85c 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -1944,6 +1944,13 @@ static void rna_def_gpencil_layer_mask(BlenderRNA *brna)
   RNA_def_property_ui_icon(prop, ICON_CLIPUV_HLT, -1);
   RNA_def_property_ui_text(prop, "Invert", "Invert mask");
   RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+  prop = RNA_def_property(srna, "intersect", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_MASK_INTERSECT);
+  // TODO (antoniov) Better icon
+  RNA_def_property_ui_icon(prop, ICON_RADIOBUT_OFF, 1);
+  RNA_def_property_ui_text(prop, "Intersect", "Intersect mask");
+  RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
 }
 
 static void rna_def_gpencil_layer(BlenderRNA *brna)



More information about the Bf-blender-cvs mailing list