forked from blender/blender
GPv3: Add Compound Shapes Rendering (i.e. Hole rendering) #12
@ -54,7 +54,7 @@ class DrawingRuntime {
|
|||||||
/**
|
/**
|
||||||
* Triangle cache for all the strokes in the drawing.
|
* Triangle cache for all the strokes in the drawing.
|
||||||
*/
|
*/
|
||||||
mutable SharedCache<Vector<uint3>> triangles_cache;
|
mutable SharedCache<Vector<Vector<uint3>>> triangles_cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normal vector cache for every stroke. Computed using Newell's method.
|
* Normal vector cache for every stroke. Computed using Newell's method.
|
||||||
@ -89,7 +89,7 @@ class Drawing : public ::GreasePencilDrawing {
|
|||||||
/**
|
/**
|
||||||
* The triangles for all the fills in the geometry.
|
* The triangles for all the fills in the geometry.
|
||||||
*/
|
*/
|
||||||
Span<uint3> triangles() const;
|
Span<Vector<uint3>> triangles() const;
|
||||||
/**
|
/**
|
||||||
* Normal vectors for a plane that fits the stroke.
|
* Normal vectors for a plane that fits the stroke.
|
||||||
*/
|
*/
|
||||||
|
@ -366,7 +366,7 @@ Drawing::~Drawing()
|
|||||||
this->runtime = nullptr;
|
this->runtime = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Span<uint3> Drawing::triangles() const
|
Span<Vector<uint3>> Drawing::triangles() const
|
||||||
{
|
{
|
||||||
struct LocalMemArena {
|
struct LocalMemArena {
|
||||||
MemArena *pf_arena = nullptr;
|
MemArena *pf_arena = nullptr;
|
||||||
@ -379,24 +379,14 @@ Span<uint3> Drawing::triangles() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this->runtime->triangles_cache.ensure([&](Vector<uint3> &r_data) {
|
this->runtime->triangles_cache.ensure([&](Vector<Vector<uint3>> &r_data) {
|
||||||
const CurvesGeometry &curves = this->strokes();
|
const CurvesGeometry &curves = this->strokes();
|
||||||
const Span<float3> positions = curves.evaluated_positions();
|
const Span<float3> positions = curves.evaluated_positions();
|
||||||
const Span<float3> normals = this->curve_plane_normals();
|
const Span<float3> normals = this->curve_plane_normals();
|
||||||
const OffsetIndices<int> points_by_curve = curves.evaluated_points_by_curve();
|
const OffsetIndices<int> points_by_curve = curves.evaluated_points_by_curve();
|
||||||
|
|
||||||
int total_triangles = 0;
|
r_data.resize(curves.curves_num());
|
||||||
Array<int> tris_offests(curves.curves_num());
|
MutableSpan<Vector<uint3>> strokes_triangles = r_data.as_mutable_span();
|
||||||
for (int curve_i : curves.curves_range()) {
|
|
||||||
IndexRange points = points_by_curve[curve_i];
|
|
||||||
if (points.size() > 2) {
|
|
||||||
tris_offests[curve_i] = total_triangles;
|
|
||||||
total_triangles += points.size() - 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r_data.resize(total_triangles);
|
|
||||||
MutableSpan<uint3> triangles = r_data.as_mutable_span();
|
|
||||||
threading::EnumerableThreadSpecific<LocalMemArena> all_local_mem_arenas;
|
threading::EnumerableThreadSpecific<LocalMemArena> all_local_mem_arenas;
|
||||||
threading::parallel_for(curves.curves_range(), 32, [&](const IndexRange range) {
|
threading::parallel_for(curves.curves_range(), 32, [&](const IndexRange range) {
|
||||||
MemArena *pf_arena = all_local_mem_arenas.local().pf_arena;
|
MemArena *pf_arena = all_local_mem_arenas.local().pf_arena;
|
||||||
@ -407,7 +397,8 @@ Span<uint3> Drawing::triangles() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int num_triangles = points.size() - 2;
|
const int num_triangles = points.size() - 2;
|
||||||
MutableSpan<uint3> r_tris = triangles.slice(tris_offests[curve_i], num_triangles);
|
strokes_triangles[curve_i].resize(num_triangles);
|
||||||
|
MutableSpan<uint3> r_tris = strokes_triangles[curve_i];
|
||||||
|
|
||||||
float(*projverts)[2] = static_cast<float(*)[2]>(
|
float(*projverts)[2] = static_cast<float(*)[2]>(
|
||||||
BLI_memarena_alloc(pf_arena, sizeof(*projverts) * size_t(points.size())));
|
BLI_memarena_alloc(pf_arena, sizeof(*projverts) * size_t(points.size())));
|
||||||
@ -415,7 +406,7 @@ Span<uint3> Drawing::triangles() const
|
|||||||
float3x3 axis_mat;
|
float3x3 axis_mat;
|
||||||
axis_dominant_v3_to_m3(axis_mat.ptr(), normals[curve_i]);
|
axis_dominant_v3_to_m3(axis_mat.ptr(), normals[curve_i]);
|
||||||
|
|
||||||
for (const int i : IndexRange(points.size())) {
|
for (const int i : points.index_range()) {
|
||||||
mul_v2_m3v3(projverts[i], axis_mat.ptr(), positions[points[i]]);
|
mul_v2_m3v3(projverts[i], axis_mat.ptr(), positions[points[i]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,6 +415,11 @@ Span<uint3> Drawing::triangles() const
|
|||||||
0,
|
0,
|
||||||
reinterpret_cast<uint32_t(*)[3]>(r_tris.data()),
|
reinterpret_cast<uint32_t(*)[3]>(r_tris.data()),
|
||||||
pf_arena);
|
pf_arena);
|
||||||
|
|
||||||
|
for (const int i : r_tris.index_range()) {
|
||||||
|
r_tris[i] += uint3(points.first());
|
||||||
|
}
|
||||||
|
|
||||||
BLI_memarena_clear(pf_arena);
|
BLI_memarena_clear(pf_arena);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -714,6 +714,8 @@ static GPENCIL_tObject *grease_pencil_object_cache_populate(GPENCIL_PrivateData
|
|||||||
for (const DrawingInfo info : drawings) {
|
for (const DrawingInfo info : drawings) {
|
||||||
const Layer &layer = *layers[info.layer_index];
|
const Layer &layer = *layers[info.layer_index];
|
||||||
|
|
||||||
|
const Span<Vector<uint3>> triangles = info.drawing.triangles();
|
||||||
|
|
||||||
const bke::CurvesGeometry &curves = info.drawing.strokes();
|
const bke::CurvesGeometry &curves = info.drawing.strokes();
|
||||||
const OffsetIndices<int> points_by_curve = curves.evaluated_points_by_curve();
|
const OffsetIndices<int> points_by_curve = curves.evaluated_points_by_curve();
|
||||||
const bke::AttributeAccessor attributes = curves.attributes();
|
const bke::AttributeAccessor attributes = curves.attributes();
|
||||||
@ -733,7 +735,7 @@ static GPENCIL_tObject *grease_pencil_object_cache_populate(GPENCIL_PrivateData
|
|||||||
int total_num_vertices = 0;
|
int total_num_vertices = 0;
|
||||||
visible_strokes.foreach_index([&](const int stroke_i, const int pos) {
|
visible_strokes.foreach_index([&](const int stroke_i, const int pos) {
|
||||||
const IndexRange points = points_by_curve[stroke_i];
|
const IndexRange points = points_by_curve[stroke_i];
|
||||||
const int num_stroke_triangles = (points.size() >= 3) ? (points.size() - 2) : 0;
|
const int num_stroke_triangles = triangles[stroke_i].size();
|
||||||
const int num_stroke_vertices = (points.size() +
|
const int num_stroke_vertices = (points.size() +
|
||||||
int(cyclic[stroke_i] && (points.size() >= 3)));
|
int(cyclic[stroke_i] && (points.size() >= 3)));
|
||||||
num_triangles_per_stroke[pos] = num_stroke_triangles;
|
num_triangles_per_stroke[pos] = num_stroke_triangles;
|
||||||
|
@ -90,6 +90,8 @@ class GreasePencil {
|
|||||||
const IndexMask visible_strokes = ed::greasepencil::retrieve_visible_strokes(
|
const IndexMask visible_strokes = ed::greasepencil::retrieve_visible_strokes(
|
||||||
*ob, info.drawing, memory);
|
*ob, info.drawing, memory);
|
||||||
|
|
||||||
|
const Span<Vector<uint3>> triangles = info.drawing.triangles();
|
||||||
|
|
||||||
visible_strokes.foreach_index([&](const int stroke_i) {
|
visible_strokes.foreach_index([&](const int stroke_i) {
|
||||||
const IndexRange points = points_by_curve[stroke_i];
|
const IndexRange points = points_by_curve[stroke_i];
|
||||||
const int material_index = stroke_materials[stroke_i];
|
const int material_index = stroke_materials[stroke_i];
|
||||||
@ -98,7 +100,7 @@ class GreasePencil {
|
|||||||
const bool hide_onion = info.onion_id != 0;
|
const bool hide_onion = info.onion_id != 0;
|
||||||
const bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
|
const bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
|
||||||
|
|
||||||
const int num_stroke_triangles = (points.size() >= 3) ? (points.size() - 2) : 0;
|
const int num_stroke_triangles = triangles[stroke_i].size();
|
||||||
const int num_stroke_vertices = (points.size() +
|
const int num_stroke_vertices = (points.size() +
|
||||||
int(cyclic[stroke_i] && (points.size() >= 3)));
|
int(cyclic[stroke_i] && (points.size() >= 3)));
|
||||||
|
|
||||||
|
@ -324,6 +324,8 @@ static void OVERLAY_outline_grease_pencil(OVERLAY_PrivateData *pd, Scene *scene,
|
|||||||
const IndexMask visible_strokes = ed::greasepencil::retrieve_visible_strokes(
|
const IndexMask visible_strokes = ed::greasepencil::retrieve_visible_strokes(
|
||||||
*ob, info.drawing, memory);
|
*ob, info.drawing, memory);
|
||||||
|
|
||||||
|
const Span<Vector<uint3>> triangles = info.drawing.triangles();
|
||||||
|
|
||||||
visible_strokes.foreach_index([&](const int stroke_i) {
|
visible_strokes.foreach_index([&](const int stroke_i) {
|
||||||
const IndexRange points = points_by_curve[stroke_i];
|
const IndexRange points = points_by_curve[stroke_i];
|
||||||
const int material_index = stroke_materials[stroke_i];
|
const int material_index = stroke_materials[stroke_i];
|
||||||
@ -332,7 +334,7 @@ static void OVERLAY_outline_grease_pencil(OVERLAY_PrivateData *pd, Scene *scene,
|
|||||||
const bool hide_onion = info.onion_id != 0;
|
const bool hide_onion = info.onion_id != 0;
|
||||||
const bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
|
const bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
|
||||||
|
|
||||||
const int num_stroke_triangles = (points.size() >= 3) ? (points.size() - 2) : 0;
|
const int num_stroke_triangles = triangles[stroke_i].size();
|
||||||
const int num_stroke_vertices = (points.size() +
|
const int num_stroke_vertices = (points.size() +
|
||||||
int(cyclic[stroke_i] && (points.size() >= 3)));
|
int(cyclic[stroke_i] && (points.size() >= 3)));
|
||||||
|
|
||||||
|
@ -1043,7 +1043,6 @@ static void grease_pencil_geom_batch_ensure(Object &object,
|
|||||||
int total_triangles_num = 0;
|
int total_triangles_num = 0;
|
||||||
int v_offset = 0;
|
int v_offset = 0;
|
||||||
Vector<Array<int>> verts_start_offsets_per_visible_drawing;
|
Vector<Array<int>> verts_start_offsets_per_visible_drawing;
|
||||||
Vector<Array<int>> tris_start_offsets_per_visible_drawing;
|
|
||||||
for (const ed::greasepencil::DrawingInfo &info : drawings) {
|
for (const ed::greasepencil::DrawingInfo &info : drawings) {
|
||||||
const bke::CurvesGeometry &curves = info.drawing.strokes();
|
const bke::CurvesGeometry &curves = info.drawing.strokes();
|
||||||
const OffsetIndices<int> points_by_curve = curves.evaluated_points_by_curve();
|
const OffsetIndices<int> points_by_curve = curves.evaluated_points_by_curve();
|
||||||
@ -1054,23 +1053,7 @@ static void grease_pencil_geom_batch_ensure(Object &object,
|
|||||||
|
|
||||||
const int num_curves = visible_strokes.size();
|
const int num_curves = visible_strokes.size();
|
||||||
const int verts_start_offsets_size = num_curves;
|
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> verts_start_offsets(verts_start_offsets_size);
|
||||||
Array<int> tris_start_offsets(tris_start_offsets_size);
|
|
||||||
|
|
||||||
/* Calculate the triangle offsets for all the visible curves. */
|
|
||||||
int t_offset = 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. */
|
/* Calculate the vertex offsets for all the visible curves. */
|
||||||
int num_cyclic = 0;
|
int num_cyclic = 0;
|
||||||
@ -1091,10 +1074,12 @@ static void grease_pencil_geom_batch_ensure(Object &object,
|
|||||||
/* One vertex is stored before and after as padding. Cyclic strokes have one extra vertex. */
|
/* One vertex is stored before and after as padding. Cyclic strokes have one extra vertex. */
|
||||||
total_verts_num += num_points + num_cyclic + num_curves * 2;
|
total_verts_num += num_points + num_cyclic + num_curves * 2;
|
||||||
total_triangles_num += (num_points + num_cyclic) * 2;
|
total_triangles_num += (num_points + num_cyclic) * 2;
|
||||||
total_triangles_num += info.drawing.triangles().size();
|
|
||||||
|
for (const int curve_i : curves.curves_range()) {
|
||||||
|
total_triangles_num += info.drawing.triangles()[curve_i].size();
|
||||||
|
}
|
||||||
|
|
||||||
verts_start_offsets_per_visible_drawing.append(std::move(verts_start_offsets));
|
verts_start_offsets_per_visible_drawing.append(std::move(verts_start_offsets));
|
||||||
tris_start_offsets_per_visible_drawing.append(std::move(tris_start_offsets));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUUsageType vbo_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY;
|
GPUUsageType vbo_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY;
|
||||||
@ -1161,10 +1146,9 @@ static void grease_pencil_geom_batch_ensure(Object &object,
|
|||||||
const VArray<float> fill_opacities = *attributes.lookup_or_default<float>(
|
const VArray<float> fill_opacities = *attributes.lookup_or_default<float>(
|
||||||
"fill_opacity", bke::AttrDomain::Curve, 1.0f);
|
"fill_opacity", bke::AttrDomain::Curve, 1.0f);
|
||||||
|
|
||||||
const Span<uint3> triangles = info.drawing.triangles();
|
const Span<Vector<uint3>> triangles = info.drawing.triangles();
|
||||||
const Span<float4x2> texture_matrices = info.drawing.texture_matrices();
|
const Span<float4x2> texture_matrices = info.drawing.texture_matrices();
|
||||||
const Span<int> verts_start_offsets = verts_start_offsets_per_visible_drawing[drawing_i];
|
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;
|
IndexMaskMemory memory;
|
||||||
const IndexMask visible_strokes = ed::greasepencil::retrieve_visible_strokes(
|
const IndexMask visible_strokes = ed::greasepencil::retrieve_visible_strokes(
|
||||||
object, info.drawing, memory);
|
object, info.drawing, memory);
|
||||||
@ -1214,7 +1198,6 @@ static void grease_pencil_geom_batch_ensure(Object &object,
|
|||||||
const IndexRange points = points_by_curve[curve_i];
|
const IndexRange points = points_by_curve[curve_i];
|
||||||
const bool is_cyclic = cyclic[curve_i] && (points.size() > 2);
|
const bool is_cyclic = cyclic[curve_i] && (points.size() > 2);
|
||||||
const int verts_start_offset = verts_start_offsets[pos];
|
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;
|
const int num_verts = 1 + points.size() + (is_cyclic ? 1 : 0) + 1;
|
||||||
const IndexRange verts_range = IndexRange(verts_start_offset, num_verts);
|
const IndexRange verts_range = IndexRange(verts_start_offset, num_verts);
|
||||||
MutableSpan<GreasePencilStrokeVert> verts_slice = verts.slice(verts_range);
|
MutableSpan<GreasePencilStrokeVert> verts_slice = verts.slice(verts_range);
|
||||||
@ -1228,12 +1211,13 @@ static void grease_pencil_geom_batch_ensure(Object &object,
|
|||||||
|
|
||||||
/* If the stroke has more than 2 points, add the triangle indices to the index buffer. */
|
/* If the stroke has more than 2 points, add the triangle indices to the index buffer. */
|
||||||
if (points.size() >= 3) {
|
if (points.size() >= 3) {
|
||||||
const Span<uint3> tris_slice = triangles.slice(tris_start_offset, points.size() - 2);
|
const Span<uint3> tris_slice = triangles[curve_i];
|
||||||
for (const uint3 tri : tris_slice) {
|
for (const uint3 tri : tris_slice) {
|
||||||
GPU_indexbuf_add_tri_verts(&ibo,
|
GPU_indexbuf_add_tri_verts(
|
||||||
(verts_range[1] + tri.x) << GP_VERTEX_ID_SHIFT,
|
&ibo,
|
||||||
(verts_range[1] + tri.y) << GP_VERTEX_ID_SHIFT,
|
(verts_range.first() + tri.x - points.first() + 1) << GP_VERTEX_ID_SHIFT,
|
||||||
(verts_range[1] + tri.z) << GP_VERTEX_ID_SHIFT);
|
(verts_range.first() + tri.y - points.first() + 1) << GP_VERTEX_ID_SHIFT,
|
||||||
|
(verts_range.first() + tri.z - points.first() + 1) << GP_VERTEX_ID_SHIFT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user