static int mask_flood_fill_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); Object *ob = CTX_data_active_object(C); PaintMaskFloodMode mode; float value; DerivedMesh *dm; PBVH *pbvh; PBVHNode **nodes; int totnode, i; mode = RNA_enum_get(op->ptr, "mode"); value = RNA_float_get(op->ptr, "value"); dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); pbvh = dm->getPBVH(ob, dm); ob->sculpt->pbvh = pbvh; BLI_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode); sculpt_undo_push_begin("Mask flood fill"); for (i = 0; i < totnode; i++) { PBVHVertexIter vi; sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK); BLI_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) { mask_flood_fill_set_elem(vi.mask, mode, value); } BLI_pbvh_vertex_iter_end; BLI_pbvh_node_mark_update(nodes[i]); if (BLI_pbvh_type(pbvh) == PBVH_GRIDS) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); }
static int mask_flood_fill_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); struct Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); struct MultiresModifierData *mmd = sculpt_multires_active(scene, ob); PaintMaskFloodMode mode; float value; DerivedMesh *dm; PBVH *pbvh; PBVHNode **nodes; int totnode, i; #ifdef _OPENMP Sculpt *sd = CTX_data_tool_settings(C)->sculpt; #endif mode = RNA_enum_get(op->ptr, "mode"); value = RNA_float_get(op->ptr, "value"); ED_sculpt_mask_layers_ensure(ob, mmd); dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); pbvh = dm->getPBVH(ob, dm); ob->sculpt->pbvh = pbvh; BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode); sculpt_undo_push_begin("Mask flood fill"); #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) for (i = 0; i < totnode; i++) { PBVHVertexIter vi; sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK); BKE_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) { mask_flood_fill_set_elem(vi.mask, mode, value); } BKE_pbvh_vertex_iter_end; BKE_pbvh_node_mark_redraw(nodes[i]); if (BKE_pbvh_type(pbvh) == PBVH_GRIDS) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); }
/* Hide or show elements in multires grids with a special GridFlags * customdata layer. */ static void partialvis_update_grids(Object *ob, PBVH *pbvh, PBVHNode *node, PartialVisAction action, PartialVisArea area, float planes[4][4]) { CCGElem **grids; CCGKey key; BLI_bitmap **grid_hidden; int *grid_indices, totgrid, i; bool any_changed = false, any_visible = false; /* get PBVH data */ BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, NULL, &grids, NULL); grid_hidden = BKE_pbvh_grid_hidden(pbvh); BKE_pbvh_get_grid_key(pbvh, &key); sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN); for (i = 0; i < totgrid; i++) { int any_hidden = 0; int g = grid_indices[i], x, y; BLI_bitmap *gh = grid_hidden[g]; if (!gh) { switch (action) { case PARTIALVIS_HIDE: /* create grid flags data */ gh = grid_hidden[g] = BLI_BITMAP_NEW(key.grid_area, "partialvis_update_grids"); break; case PARTIALVIS_SHOW: /* entire grid is visible, nothing to show */ continue; } } else if (action == PARTIALVIS_SHOW && area == PARTIALVIS_ALL) { /* special case if we're showing all, just free the * grid */ MEM_freeN(gh); grid_hidden[g] = NULL; any_changed = true; any_visible = true; continue; } for (y = 0; y < key.grid_size; y++) { for (x = 0; x < key.grid_size; x++) { CCGElem *elem = CCG_grid_elem(&key, grids[g], x, y); const float *co = CCG_elem_co(&key, elem); float mask = key.has_mask ? *CCG_elem_mask(&key, elem) : 0.0f; /* skip grid element if not in the effected area */ if (is_effected(area, planes, co, mask)) { /* set or clear the hide flag */ BLI_BITMAP_MODIFY(gh, y * key.grid_size + x, action == PARTIALVIS_HIDE); any_changed = true; } /* keep track of whether any elements are still hidden */ if (BLI_BITMAP_GET(gh, y * key.grid_size + x)) any_hidden = true; else any_visible = true; } } /* if everything in the grid is now visible, free the grid * flags */ if (!any_hidden) { MEM_freeN(gh); grid_hidden[g] = NULL; } } /* mark updates if anything was hidden/shown */ if (any_changed) { BKE_pbvh_node_mark_rebuild_draw(node); BKE_pbvh_node_fully_hidden_set(node, !any_visible); multires_mark_as_modified(ob, MULTIRES_HIDDEN_MODIFIED); } }