GPv3: Overlay: Only show visible and editable materials
This PR makes it so that locked materials as well as hidden materials will not have their edit points and edit lines visible. Note: Previously in grease pencil, strokes with hidden materials would still display the edit lines. This behavior is now fixed in GPv3. Pull Request: https://projects.blender.org/blender/blender/pulls/115740
This commit is contained in:
committed by
Falk David
parent
9ddd5126fe
commit
58041799bc
@@ -222,6 +222,7 @@ void invert_booleans(MutableSpan<bool> span);
|
||||
void invert_booleans(MutableSpan<bool> span, const IndexMask &mask);
|
||||
|
||||
int64_t count_booleans(const VArray<bool> &varray);
|
||||
int64_t count_booleans(const VArray<bool> &varray, const IndexMask &mask);
|
||||
|
||||
enum class BooleanMix {
|
||||
None,
|
||||
|
||||
@@ -141,40 +141,59 @@ BooleanMix booleans_mix_calc(const VArray<bool> &varray, const IndexRange range_
|
||||
[&](BooleanMix a, BooleanMix b) { return (a == b) ? a : BooleanMix::Mixed; });
|
||||
}
|
||||
|
||||
int64_t count_booleans(const VArray<bool> &varray)
|
||||
int64_t count_booleans(const VArray<bool> &varray, const IndexMask &mask)
|
||||
{
|
||||
if (varray.is_empty()) {
|
||||
if (varray.is_empty() || mask.is_empty()) {
|
||||
return 0;
|
||||
}
|
||||
const CommonVArrayInfo info = varray.common_info();
|
||||
if (info.type == CommonVArrayInfo::Type::Single) {
|
||||
return *static_cast<const bool *>(info.data) ? varray.size() : 0;
|
||||
}
|
||||
if (info.type == CommonVArrayInfo::Type::Span) {
|
||||
const Span<bool> span(static_cast<const bool *>(info.data), varray.size());
|
||||
/* Check if mask is full. */
|
||||
if (varray.size() == mask.size()) {
|
||||
const CommonVArrayInfo info = varray.common_info();
|
||||
if (info.type == CommonVArrayInfo::Type::Single) {
|
||||
return *static_cast<const bool *>(info.data) ? varray.size() : 0;
|
||||
}
|
||||
if (info.type == CommonVArrayInfo::Type::Span) {
|
||||
const Span<bool> span(static_cast<const bool *>(info.data), varray.size());
|
||||
return threading::parallel_reduce(
|
||||
varray.index_range(),
|
||||
4096,
|
||||
0,
|
||||
[&](const IndexRange range, const int64_t init) {
|
||||
const Span<bool> slice = span.slice(range);
|
||||
return init + std::count(slice.begin(), slice.end(), true);
|
||||
},
|
||||
std::plus<int64_t>());
|
||||
}
|
||||
return threading::parallel_reduce(
|
||||
varray.index_range(),
|
||||
4096,
|
||||
2048,
|
||||
0,
|
||||
[&](const IndexRange range, const int64_t init) {
|
||||
const Span<bool> slice = span.slice(range);
|
||||
return init + std::count(slice.begin(), slice.end(), true);
|
||||
int64_t value = init;
|
||||
/* Alternatively, this could use #materialize to retrieve many values at once. */
|
||||
for (const int64_t i : range) {
|
||||
value += int64_t(varray[i]);
|
||||
}
|
||||
return value;
|
||||
},
|
||||
std::plus<int64_t>());
|
||||
}
|
||||
return threading::parallel_reduce(
|
||||
varray.index_range(),
|
||||
2048,
|
||||
0,
|
||||
[&](const IndexRange range, const int64_t init) {
|
||||
int64_t value = init;
|
||||
/* Alternatively, this could use #materialize to retrieve many values at once. */
|
||||
for (const int64_t i : range) {
|
||||
value += int64_t(varray[i]);
|
||||
}
|
||||
return value;
|
||||
},
|
||||
std::plus<int64_t>());
|
||||
const CommonVArrayInfo info = varray.common_info();
|
||||
if (info.type == CommonVArrayInfo::Type::Single) {
|
||||
return *static_cast<const bool *>(info.data) ? mask.size() : 0;
|
||||
}
|
||||
int64_t value = 0;
|
||||
mask.foreach_segment([&](const IndexMaskSegment segment) {
|
||||
for (const int64_t i : segment) {
|
||||
value += int64_t(varray[i]);
|
||||
}
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
int64_t count_booleans(const VArray<bool> &varray)
|
||||
{
|
||||
return count_booleans(varray, IndexMask(varray.size()));
|
||||
}
|
||||
|
||||
} // namespace blender::array_utils
|
||||
|
||||
@@ -198,7 +198,9 @@ BLI_INLINE int32_t pack_rotation_aspect_hardness(float rot, float asp, float har
|
||||
return packed;
|
||||
}
|
||||
|
||||
static void grease_pencil_edit_batch_ensure(const GreasePencil &grease_pencil, const Scene &scene)
|
||||
static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
const GreasePencil &grease_pencil,
|
||||
const Scene &scene)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
BLI_assert(grease_pencil.runtime != nullptr);
|
||||
@@ -249,6 +251,10 @@ static void grease_pencil_edit_batch_ensure(const GreasePencil &grease_pencil, c
|
||||
const bke::CurvesGeometry &curves = info.drawing.strokes();
|
||||
const bke::AttributeAccessor attributes = curves.attributes();
|
||||
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
|
||||
const VArray<bool> cyclic = curves.cyclic();
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask editable_strokes = ed::greasepencil::retrieve_editable_strokes(
|
||||
object, info.drawing, memory);
|
||||
|
||||
/* Assumes that if the ".selection" attribute does not exist, all points are selected. */
|
||||
const VArray<float> selection_float = *attributes.lookup_or_default<float>(
|
||||
@@ -267,11 +273,15 @@ static void grease_pencil_edit_batch_ensure(const GreasePencil &grease_pencil, c
|
||||
drawing_start_offset += curves.points_num();
|
||||
|
||||
/* Add one id for the restart after every curve. */
|
||||
total_line_ids_num += curves.curves_num();
|
||||
total_line_ids_num += editable_strokes.size();
|
||||
Array<int> size_per_editable_stroke(editable_strokes.size());
|
||||
offset_indices::gather_group_sizes(
|
||||
points_by_curve, editable_strokes, size_per_editable_stroke);
|
||||
/* Add one id for every non-cyclic segment. */
|
||||
total_line_ids_num += curves.points_num();
|
||||
total_line_ids_num += std::accumulate(
|
||||
size_per_editable_stroke.begin(), size_per_editable_stroke.end(), 0);
|
||||
/* Add one id for the last segment of every cyclic curve. */
|
||||
total_line_ids_num += array_utils::count_booleans(curves.cyclic());
|
||||
total_line_ids_num += array_utils::count_booleans(curves.cyclic(), editable_strokes);
|
||||
|
||||
/* Do not show points for locked layers. */
|
||||
if (layer->is_locked()) {
|
||||
@@ -281,12 +291,12 @@ static void grease_pencil_edit_batch_ensure(const GreasePencil &grease_pencil, c
|
||||
const VArray<bool> selection = *attributes.lookup_or_default<bool>(
|
||||
".selection", ATTR_DOMAIN_POINT, true);
|
||||
|
||||
for (const int curve_i : curves.curves_range()) {
|
||||
editable_strokes.foreach_index([&](const int curve_i) {
|
||||
const IndexRange points = points_by_curve[curve_i];
|
||||
if (ed::curves::has_anything_selected(selection, points)) {
|
||||
visible_points_num += points.size();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GPUIndexBufBuilder elb;
|
||||
@@ -308,23 +318,24 @@ static void grease_pencil_edit_batch_ensure(const GreasePencil &grease_pencil, c
|
||||
const bke::CurvesGeometry &curves = info.drawing.strokes();
|
||||
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
|
||||
const VArray<bool> cyclic = curves.cyclic();
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask editable_strokes = ed::greasepencil::retrieve_editable_strokes(
|
||||
object, info.drawing, memory);
|
||||
|
||||
/* Fill line indices. */
|
||||
threading::parallel_for(curves.curves_range(), 512, [&](IndexRange range) {
|
||||
for (const int curve_i : range) {
|
||||
const IndexRange points = points_by_curve[curve_i];
|
||||
const bool is_cyclic = cyclic[curve_i];
|
||||
editable_strokes.foreach_index([&](const int curve_i) {
|
||||
const IndexRange points = points_by_curve[curve_i];
|
||||
const bool is_cyclic = cyclic[curve_i];
|
||||
|
||||
for (const int point : points) {
|
||||
GPU_indexbuf_add_generic_vert(&elb, point + drawing_start_offset);
|
||||
}
|
||||
|
||||
if (is_cyclic) {
|
||||
GPU_indexbuf_add_generic_vert(&elb, points.first() + drawing_start_offset);
|
||||
}
|
||||
|
||||
GPU_indexbuf_add_primitive_restart(&elb);
|
||||
for (const int point_i : points) {
|
||||
GPU_indexbuf_add_generic_vert(&elb, point_i + drawing_start_offset);
|
||||
}
|
||||
|
||||
if (is_cyclic) {
|
||||
GPU_indexbuf_add_generic_vert(&elb, points.first() + drawing_start_offset);
|
||||
}
|
||||
|
||||
GPU_indexbuf_add_primitive_restart(&elb);
|
||||
});
|
||||
|
||||
/* Assumes that if the ".selection" attribute does not exist, all points are selected. */
|
||||
@@ -333,16 +344,14 @@ static void grease_pencil_edit_batch_ensure(const GreasePencil &grease_pencil, c
|
||||
|
||||
/* Fill point indices. */
|
||||
if (!layer->is_locked()) {
|
||||
threading::parallel_for(curves.curves_range(), 512, [&](IndexRange range) {
|
||||
for (const int curve_i : range) {
|
||||
const IndexRange points = points_by_curve[curve_i];
|
||||
if (!ed::curves::has_anything_selected(selection, points)) {
|
||||
continue;
|
||||
}
|
||||
editable_strokes.foreach_index([&](const int curve_i) {
|
||||
const IndexRange points = points_by_curve[curve_i];
|
||||
if (!ed::curves::has_anything_selected(selection, points)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const int point : points) {
|
||||
GPU_indexbuf_add_generic_vert(&epb, point + drawing_start_offset);
|
||||
}
|
||||
for (const int point : points) {
|
||||
GPU_indexbuf_add_generic_vert(&epb, point + drawing_start_offset);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -365,7 +374,9 @@ static void grease_pencil_edit_batch_ensure(const GreasePencil &grease_pencil, c
|
||||
cache->is_dirty = false;
|
||||
}
|
||||
|
||||
static void grease_pencil_geom_batch_ensure(const GreasePencil &grease_pencil, const Scene &scene)
|
||||
static void grease_pencil_geom_batch_ensure(Object &object,
|
||||
const GreasePencil &grease_pencil,
|
||||
const Scene &scene)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
BLI_assert(grease_pencil.runtime != nullptr);
|
||||
@@ -386,7 +397,6 @@ static void grease_pencil_geom_batch_ensure(const GreasePencil &grease_pencil, c
|
||||
|
||||
/* First, count how many vertices and triangles are needed for the whole object. Also record the
|
||||
* offsets into the curves for the vertices and triangles. */
|
||||
// int total_points_num = 0; /* UNUSED. */
|
||||
int total_verts_num = 0;
|
||||
int total_triangles_num = 0;
|
||||
int v_offset = 0;
|
||||
@@ -396,16 +406,34 @@ static void grease_pencil_geom_batch_ensure(const GreasePencil &grease_pencil, c
|
||||
const bke::CurvesGeometry &curves = info.drawing.strokes();
|
||||
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
|
||||
const VArray<bool> cyclic = curves.cyclic();
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask visible_strokes = ed::greasepencil::retrieve_visible_strokes(
|
||||
object, info.drawing, memory);
|
||||
|
||||
int verts_start_offsets_size = curves.curves_num();
|
||||
int tris_start_offsets_size = curves.curves_num();
|
||||
const int num_curves = visible_strokes.size();
|
||||
const int verts_start_offsets_size = num_curves;
|
||||
const int tris_start_offsets_size = num_curves;
|
||||
Array<int> verts_start_offsets(verts_start_offsets_size);
|
||||
Array<int> tris_start_offsets(tris_start_offsets_size);
|
||||
|
||||
/* Calculate the vertex and triangle offsets for all the curves. */
|
||||
/* Calculate the triangle offsets for all the visible curves. */
|
||||
int t_offset = 0;
|
||||
int num_cyclic = 0;
|
||||
int pos = 0;
|
||||
for (const int curve_i : curves.curves_range()) {
|
||||
IndexRange points = points_by_curve[curve_i];
|
||||
if (visible_strokes.contains(curve_i)) {
|
||||
tris_start_offsets[pos] = t_offset;
|
||||
pos++;
|
||||
}
|
||||
if (points.size() >= 3) {
|
||||
t_offset += points.size() - 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate the vertex offsets for all the visible curves. */
|
||||
int num_cyclic = 0;
|
||||
int num_points = 0;
|
||||
visible_strokes.foreach_index([&](const int curve_i, const int pos) {
|
||||
IndexRange points = points_by_curve[curve_i];
|
||||
const bool is_cyclic = cyclic[curve_i];
|
||||
|
||||
@@ -413,20 +441,14 @@ static void grease_pencil_geom_batch_ensure(const GreasePencil &grease_pencil, c
|
||||
num_cyclic++;
|
||||
}
|
||||
|
||||
tris_start_offsets[curve_i] = t_offset;
|
||||
if (points.size() >= 3) {
|
||||
t_offset += points.size() - 2;
|
||||
}
|
||||
|
||||
verts_start_offsets[curve_i] = v_offset;
|
||||
verts_start_offsets[pos] = v_offset;
|
||||
v_offset += 1 + points.size() + (is_cyclic ? 1 : 0) + 1;
|
||||
}
|
||||
|
||||
// total_points_num += curves.points_num(); /* UNUSED. */
|
||||
num_points += points.size();
|
||||
});
|
||||
|
||||
/* One vertex is stored before and after as padding. Cyclic strokes have one extra vertex. */
|
||||
total_verts_num += curves.points_num() + num_cyclic + curves.curves_num() * 2;
|
||||
total_triangles_num += (curves.points_num() + num_cyclic) * 2;
|
||||
total_verts_num += num_points + num_cyclic + num_curves * 2;
|
||||
total_triangles_num += (num_points + num_cyclic) * 2;
|
||||
total_triangles_num += info.drawing.triangles().size();
|
||||
|
||||
verts_start_offsets_per_visible_drawing.append(std::move(verts_start_offsets));
|
||||
@@ -477,6 +499,9 @@ static void grease_pencil_geom_batch_ensure(const GreasePencil &grease_pencil, c
|
||||
const Span<uint3> triangles = info.drawing.triangles();
|
||||
const Span<int> verts_start_offsets = verts_start_offsets_per_visible_drawing[drawing_i];
|
||||
const Span<int> tris_start_offsets = tris_start_offsets_per_visible_drawing[drawing_i];
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask visible_strokes = ed::greasepencil::retrieve_visible_strokes(
|
||||
object, info.drawing, memory);
|
||||
|
||||
auto populate_point = [&](IndexRange verts_range,
|
||||
int curve_i,
|
||||
@@ -510,59 +535,57 @@ static void grease_pencil_geom_batch_ensure(const GreasePencil &grease_pencil, c
|
||||
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 2, v_mat + 1, v_mat + 3);
|
||||
};
|
||||
|
||||
threading::parallel_for(curves.curves_range(), 512, [&](IndexRange range) {
|
||||
for (const int curve_i : range) {
|
||||
IndexRange points = points_by_curve[curve_i];
|
||||
const bool is_cyclic = cyclic[curve_i];
|
||||
const int verts_start_offset = verts_start_offsets[curve_i];
|
||||
const int tris_start_offset = tris_start_offsets[curve_i];
|
||||
const int num_verts = 1 + points.size() + (is_cyclic ? 1 : 0) + 1;
|
||||
IndexRange verts_range = IndexRange(verts_start_offset, num_verts);
|
||||
MutableSpan<GreasePencilStrokeVert> verts_slice = verts.slice(verts_range);
|
||||
MutableSpan<GreasePencilColorVert> cols_slice = cols.slice(verts_range);
|
||||
visible_strokes.foreach_index([&](const int curve_i, const int pos) {
|
||||
IndexRange points = points_by_curve[curve_i];
|
||||
const bool is_cyclic = cyclic[curve_i];
|
||||
const int verts_start_offset = verts_start_offsets[pos];
|
||||
const int tris_start_offset = tris_start_offsets[pos];
|
||||
const int num_verts = 1 + points.size() + (is_cyclic ? 1 : 0) + 1;
|
||||
IndexRange verts_range = IndexRange(verts_start_offset, num_verts);
|
||||
MutableSpan<GreasePencilStrokeVert> verts_slice = verts.slice(verts_range);
|
||||
MutableSpan<GreasePencilColorVert> cols_slice = cols.slice(verts_range);
|
||||
|
||||
/* First vertex is not drawn. */
|
||||
verts_slice.first().mat = -1;
|
||||
/* First vertex is not drawn. */
|
||||
verts_slice.first().mat = -1;
|
||||
|
||||
/* If the stroke has more than 2 points, add the triangle indices to the index buffer. */
|
||||
if (points.size() >= 3) {
|
||||
const Span<uint3> tris_slice = triangles.slice(tris_start_offset, points.size() - 2);
|
||||
for (const uint3 tri : tris_slice) {
|
||||
GPU_indexbuf_add_tri_verts(&ibo,
|
||||
(verts_range[1] + tri.x) << GP_VERTEX_ID_SHIFT,
|
||||
(verts_range[1] + tri.y) << GP_VERTEX_ID_SHIFT,
|
||||
(verts_range[1] + tri.z) << GP_VERTEX_ID_SHIFT);
|
||||
}
|
||||
/* If the stroke has more than 2 points, add the triangle indices to the index buffer. */
|
||||
if (points.size() >= 3) {
|
||||
const Span<uint3> tris_slice = triangles.slice(tris_start_offset, points.size() - 2);
|
||||
for (const uint3 tri : tris_slice) {
|
||||
GPU_indexbuf_add_tri_verts(&ibo,
|
||||
(verts_range[1] + tri.x) << GP_VERTEX_ID_SHIFT,
|
||||
(verts_range[1] + tri.y) << GP_VERTEX_ID_SHIFT,
|
||||
(verts_range[1] + tri.z) << GP_VERTEX_ID_SHIFT);
|
||||
}
|
||||
|
||||
/* Write all the point attributes to the vertex buffers. Create a quad for each point. */
|
||||
for (const int i : IndexRange(points.size())) {
|
||||
const int idx = i + 1;
|
||||
populate_point(verts_range,
|
||||
curve_i,
|
||||
start_caps[curve_i],
|
||||
end_caps[curve_i],
|
||||
points[i],
|
||||
idx,
|
||||
verts_slice[idx],
|
||||
cols_slice[idx]);
|
||||
}
|
||||
|
||||
if (is_cyclic) {
|
||||
const int idx = points.size() + 1;
|
||||
populate_point(verts_range,
|
||||
curve_i,
|
||||
start_caps[curve_i],
|
||||
end_caps[curve_i],
|
||||
points[0],
|
||||
idx,
|
||||
verts_slice[idx],
|
||||
cols_slice[idx]);
|
||||
}
|
||||
|
||||
/* Last vertex is not drawn. */
|
||||
verts_slice.last().mat = -1;
|
||||
}
|
||||
|
||||
/* Write all the point attributes to the vertex buffers. Create a quad for each point. */
|
||||
for (const int i : IndexRange(points.size())) {
|
||||
const int idx = i + 1;
|
||||
populate_point(verts_range,
|
||||
curve_i,
|
||||
start_caps[curve_i],
|
||||
end_caps[curve_i],
|
||||
points[i],
|
||||
idx,
|
||||
verts_slice[idx],
|
||||
cols_slice[idx]);
|
||||
}
|
||||
|
||||
if (is_cyclic) {
|
||||
const int idx = points.size() + 1;
|
||||
populate_point(verts_range,
|
||||
curve_i,
|
||||
start_caps[curve_i],
|
||||
end_caps[curve_i],
|
||||
points[0],
|
||||
idx,
|
||||
verts_slice[idx],
|
||||
cols_slice[idx]);
|
||||
}
|
||||
|
||||
/* Last vertex is not drawn. */
|
||||
verts_slice.last().mat = -1;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -628,7 +651,7 @@ GPUBatch *DRW_cache_grease_pencil_get(const Scene *scene, Object *ob)
|
||||
using namespace blender::draw;
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
||||
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil);
|
||||
grease_pencil_geom_batch_ensure(grease_pencil, *scene);
|
||||
grease_pencil_geom_batch_ensure(*ob, grease_pencil, *scene);
|
||||
|
||||
return cache->geom_batch;
|
||||
}
|
||||
@@ -638,7 +661,7 @@ GPUBatch *DRW_cache_grease_pencil_edit_points_get(const Scene *scene, Object *ob
|
||||
using namespace blender::draw;
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
||||
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil);
|
||||
grease_pencil_edit_batch_ensure(grease_pencil, *scene);
|
||||
grease_pencil_edit_batch_ensure(*ob, grease_pencil, *scene);
|
||||
|
||||
return cache->edit_points;
|
||||
}
|
||||
@@ -648,7 +671,7 @@ GPUBatch *DRW_cache_grease_pencil_edit_lines_get(const Scene *scene, Object *ob)
|
||||
using namespace blender::draw;
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
||||
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil);
|
||||
grease_pencil_edit_batch_ensure(grease_pencil, *scene);
|
||||
grease_pencil_edit_batch_ensure(*ob, grease_pencil, *scene);
|
||||
|
||||
return cache->edit_lines;
|
||||
}
|
||||
@@ -658,7 +681,7 @@ GPUVertBuf *DRW_cache_grease_pencil_position_buffer_get(const Scene *scene, Obje
|
||||
using namespace blender::draw;
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
||||
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil);
|
||||
grease_pencil_geom_batch_ensure(grease_pencil, *scene);
|
||||
grease_pencil_geom_batch_ensure(*ob, grease_pencil, *scene);
|
||||
|
||||
return cache->vbo;
|
||||
}
|
||||
@@ -668,7 +691,7 @@ GPUVertBuf *DRW_cache_grease_pencil_color_buffer_get(const Scene *scene, Object
|
||||
using namespace blender::draw;
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
||||
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil);
|
||||
grease_pencil_geom_batch_ensure(grease_pencil, *scene);
|
||||
grease_pencil_geom_batch_ensure(*ob, grease_pencil, *scene);
|
||||
|
||||
return cache->vbo_col;
|
||||
}
|
||||
|
||||
@@ -312,12 +312,27 @@ static VectorSet<int> get_editable_material_indices(Object &object)
|
||||
(material->gp_style->flag & GP_MATERIAL_LOCKED) == 0 &&
|
||||
(material->gp_style->flag & GP_MATERIAL_HIDE) == 0)
|
||||
{
|
||||
locked_material_indices.add(mat_i);
|
||||
locked_material_indices.add_new(mat_i);
|
||||
}
|
||||
}
|
||||
return locked_material_indices;
|
||||
}
|
||||
|
||||
static VectorSet<int> get_hidden_material_indices(Object &object)
|
||||
{
|
||||
BLI_assert(object.type == OB_GREASE_PENCIL);
|
||||
VectorSet<int> hidden_material_indices;
|
||||
for (const int mat_i : IndexRange(object.totcol)) {
|
||||
Material *material = BKE_object_material_get(&object, mat_i + 1);
|
||||
if (material != nullptr && material->gp_style != nullptr &&
|
||||
(material->gp_style->flag & GP_MATERIAL_HIDE) != 0)
|
||||
{
|
||||
hidden_material_indices.add_new(mat_i);
|
||||
}
|
||||
}
|
||||
return hidden_material_indices;
|
||||
}
|
||||
|
||||
IndexMask retrieve_editable_strokes(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
IndexMaskMemory &memory)
|
||||
@@ -327,13 +342,23 @@ IndexMask retrieve_editable_strokes(Object &object,
|
||||
/* Get all the editable material indices */
|
||||
VectorSet<int> editable_material_indices = get_editable_material_indices(object);
|
||||
|
||||
if (locked_material_indices.is_empty()) {
|
||||
return drawing.strokes().curves_range();
|
||||
}
|
||||
|
||||
const bke::CurvesGeometry &curves = drawing.strokes();
|
||||
const IndexRange curves_range = drawing.strokes().curves_range();
|
||||
const bke::AttributeAccessor attributes = curves.attributes();
|
||||
|
||||
const VArray<int> materials = *attributes.lookup<int>("material_index", ATTR_DOMAIN_CURVE);
|
||||
if (!materials) {
|
||||
/* if the attribute does not exist then the default is the first material. */
|
||||
if (locked_material_indices.contains(0)) {
|
||||
return curves_range;
|
||||
}
|
||||
return IndexMask();
|
||||
}
|
||||
/* Get all the strokes that have their material unlocked. */
|
||||
const VArray<int> materials = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_CURVE, -1);
|
||||
return IndexMask::from_predicate(
|
||||
curves_range, GrainSize(4096), memory, [&](const int64_t curve_i) {
|
||||
const int material_index = materials[curve_i];
|
||||
@@ -348,13 +373,23 @@ IndexMask retrieve_editable_points(Object &object,
|
||||
/* Get all the editable material indices */
|
||||
VectorSet<int> editable_material_indices = get_editable_material_indices(object);
|
||||
|
||||
if (locked_material_indices.is_empty()) {
|
||||
return drawing.strokes().points_range();
|
||||
}
|
||||
|
||||
const bke::CurvesGeometry &curves = drawing.strokes();
|
||||
const IndexRange points_range = drawing.strokes().points_range();
|
||||
const bke::AttributeAccessor attributes = curves.attributes();
|
||||
|
||||
/* Propagate the material index to the points. */
|
||||
const VArray<int> materials = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_POINT, -1);
|
||||
const VArray<int> materials = *attributes.lookup<int>("material_index", ATTR_DOMAIN_POINT);
|
||||
if (!materials) {
|
||||
/* if the attribute does not exist then the default is the first material. */
|
||||
if (locked_material_indices.contains(0)) {
|
||||
return points_range;
|
||||
}
|
||||
return IndexMask();
|
||||
}
|
||||
/* Get all the points that are part of a stroke with an unlocked material. */
|
||||
return IndexMask::from_predicate(
|
||||
points_range, GrainSize(4096), memory, [&](const int64_t point_i) {
|
||||
@@ -377,6 +412,33 @@ IndexMask retrieve_editable_elements(Object &object,
|
||||
return {};
|
||||
}
|
||||
|
||||
IndexMask retrieve_visible_strokes(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
using namespace blender;
|
||||
|
||||
/* Get all the hidden material indices. */
|
||||
VectorSet<int> hidden_material_indices = get_hidden_material_indices(object);
|
||||
|
||||
if (hidden_material_indices.is_empty()) {
|
||||
return drawing.strokes().curves_range();
|
||||
}
|
||||
|
||||
const bke::CurvesGeometry &curves = drawing.strokes();
|
||||
const IndexRange curves_range = drawing.strokes().curves_range();
|
||||
const bke::AttributeAccessor attributes = curves.attributes();
|
||||
|
||||
/* Get all the strokes that have their material visible. */
|
||||
const VArray<int> materials = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_CURVE, -1);
|
||||
return IndexMask::from_predicate(
|
||||
curves_range, GrainSize(4096), memory, [&](const int64_t curve_i) {
|
||||
const int material_index = materials[curve_i];
|
||||
return !hidden_material_indices.contains(material_index);
|
||||
});
|
||||
}
|
||||
|
||||
IndexMask retrieve_editable_and_selected_strokes(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
IndexMaskMemory &memory)
|
||||
|
||||
@@ -181,6 +181,10 @@ IndexMask retrieve_editable_elements(Object &object,
|
||||
eAttrDomain selection_domain,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
IndexMask retrieve_visible_strokes(Object &grease_pencil_object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
IndexMask retrieve_editable_and_selected_strokes(Object &grease_pencil_object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
Reference in New Issue
Block a user