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);
	}
Exemple #3
0
/* 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);
	}
}