Initial Grease Pencil 3.0 stage #106848

Merged
Falk David merged 224 commits from filedescriptor/blender:grease-pencil-v3 into main 2023-05-30 11:14:22 +02:00
5 changed files with 113 additions and 3 deletions
Showing only changes of commit 903e7cb07b - Show all commits

View File

@ -443,6 +443,12 @@ void legacy_gpencil_to_grease_pencil(GreasePencil &grease_pencil, bGPdata &gpd);
} // namespace gpencil
using namespace blender::bke::gpencil;
class GreasePencilDrawingRuntime {
public:
Vector<uint3> triangles_cache;
};
class GreasePencilRuntime {
private:
LayerGroup root_group_;
@ -467,7 +473,9 @@ class GreasePencilRuntime {
} // namespace blender::bke
struct Main;
struct Depsgraph;
struct BoundBox;
void *BKE_grease_pencil_add(Main *bmain, const char *name);
BoundBox *BKE_grease_pencil_boundbox_get(Object *ob);
void BKE_grease_pencil_eval_geometry(Depsgraph *depsgraph, GreasePencil &grease_pencil);

View File

@ -15,6 +15,8 @@
#include "BKE_object.h"
#include "BLI_math_vector_types.hh"
#include "BLI_memarena.h"
#include "BLI_polyfill_2d.h"
#include "BLI_span.hh"
#include "BLI_stack.hh"
@ -76,6 +78,7 @@ static void grease_pencil_copy_data(Main * /*bmain*/,
dst_drawing->base.flag = src_drawing->base.flag;
new (&dst_drawing->geometry) bke::CurvesGeometry(src_drawing->geometry.wrap());
dst_drawing->runtime = MEM_new<bke::GreasePencilDrawingRuntime>(__func__);
break;
}
case GREASE_PENCIL_DRAWING_REFERENCE: {
@ -298,6 +301,67 @@ BoundBox *BKE_grease_pencil_boundbox_get(Object *ob)
return ob->runtime.bb;
}
static void grease_pencil_drawing_calculate_fill_triangles(GreasePencilDrawing &drawing)
filedescriptor marked this conversation as resolved Outdated

Make sure to not overwrite min and max but account any value already present. E.g. use math::min_max(...).

Make sure to not overwrite `min` and `max` but account any value already present. E.g. use `math::min_max(...)`.
{
using namespace blender;
MemArena *pf_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
bke::CurvesGeometry &curves = drawing.geometry.wrap();
Span<float3> positions = curves.positions();
offset_indices::OffsetIndices<int> points_by_curve = curves.points_by_curve();
for (int curve_i : curves.curves_range()) {
IndexRange points = points_by_curve[curve_i];
int tot_verts = points.size();
int tot_tris = tot_verts - 2;
uint(*tris)[3] = static_cast<uint(*)[3]>(
BLI_memarena_alloc(pf_arena, sizeof(*tris) * size_t(tot_tris)));
float(*projverts)[2] = static_cast<float(*)[2]>(
BLI_memarena_alloc(pf_arena, sizeof(*projverts) * size_t(tot_verts)));
/* TODO: calculate axis_mat properly. */
float3x3 axis_mat;
axis_dominant_v3_to_m3(axis_mat.ptr(), float3(0.0f, -1.0f, 0.0f));
for (const int i : IndexRange(tot_verts)) {
mul_v2_m3v3(projverts[i], axis_mat.ptr(), positions[points[i]]);
}
BLI_polyfill_calc_arena(projverts, tot_verts, 1, tris, pf_arena);
for (const int i : IndexRange(tot_tris)) {
drawing.runtime->triangles_cache.append(uint3(tris[i]));
}
BLI_memarena_clear(pf_arena);
}
BLI_memarena_free(pf_arena);
}
void BKE_grease_pencil_eval_geometry(Depsgraph * /*depsgraph*/, GreasePencil &grease_pencil)
{
printf("BKE_grease_pencil_eval_geometry\n");
for (int i = 0; i < grease_pencil.drawing_array_size; i++) {
GreasePencilDrawingOrReference *drawing_or_ref = grease_pencil.drawing_array[i];
switch (drawing_or_ref->type) {
case GREASE_PENCIL_DRAWING: {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_or_ref);
BLI_assert(drawing->runtime != nullptr);
drawing->runtime->triangles_cache.clear_and_shrink();
grease_pencil_drawing_calculate_fill_triangles(*drawing);
break;
}
case GREASE_PENCIL_DRAWING_REFERENCE: {
/* Pass. */
break;
}
}
}
}
/* Draw Cache */
void (*BKE_grease_pencil_batch_cache_dirty_tag_cb)(GreasePencil *grease_pencil,
@ -364,6 +428,7 @@ void GreasePencil::read_drawing_array(BlendDataReader *reader)
/* Initialize runtime data. */
drawing->geometry.runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__);
drawing->geometry.wrap().update_curve_types();
drawing->runtime = MEM_new<blender::bke::GreasePencilDrawingRuntime>(__func__);
break;
}
case GREASE_PENCIL_DRAWING_REFERENCE: {

.as_span() shouldn't be necessary here.

`.as_span()` shouldn't be necessary here.
@ -406,6 +471,7 @@ void GreasePencil::free_drawing_array()
case GREASE_PENCIL_DRAWING: {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_or_ref);
drawing->geometry.wrap().~CurvesGeometry();
MEM_delete(drawing->runtime);
MEM_freeN(drawing);
break;
}

View File

@ -63,6 +63,7 @@
#include "BKE_fcurve_driver.h"
#include "BKE_gpencil_legacy.h"
#include "BKE_gpencil_modifier_legacy.h"
#include "BKE_grease_pencil.hh"
#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_image.h"
@ -1658,8 +1659,13 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata)
break;
}
case ID_GP: {
/* TODO */
op_node = add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
op_node = add_operation_node(obdata,
NodeType::GEOMETRY,
OperationCode::GEOMETRY_EVAL,
[obdata_cow](::Depsgraph *depsgraph) {
BKE_grease_pencil_eval_geometry(depsgraph,
*(GreasePencil *)obdata_cow);
});
op_node->set_as_entry();
break;
}

View File

@ -234,6 +234,7 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
* vertex.*/
total_points_num += curves.points_num() + num_cyclic + curves.curves_num() * 2;
total_triangles_num += (curves.points_num() + num_cyclic) * 2;
total_triangles_num += drawing.runtime->triangles_cache.size();
});
GPUUsageType vbo_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY;
@ -279,24 +280,45 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
verts[v].point_id = v;
verts[v].stroke_id = v_start;
verts[v].mat = materials[curve_i] % GPENCIL_MATERIAL_BUFFER_LEN;
/* TODO */
verts[v].packed_asp_hard_rot = pack_rotation_aspect_hardness(0.0f, 1.0f, 1.0f);
/* TODO */

These .as_span() calls shouldn't be necessary

These `.as_span()` calls shouldn't be necessary
verts[v].u_stroke = 0;
/* TODO */
verts[v].uv_fill[0] = verts[v].uv_fill[1] = 0;
/* TODO */
copy_v4_v4(cols[v].vcol, float4(0.0f, 0.0f, 0.0f, 0.0f));
copy_v4_v4(cols[v].fcol, float4(0.0f, 0.0f, 0.0f, 0.0f));
/* TODO */
cols[v].fcol[3] = (int(cols[v].fcol[3] * 10000.0f) * 10.0f) + 1.0f;
int v_mat = (v << GP_VERTEX_ID_SHIFT) | GP_IS_STROKE_VERTEX_BIT;
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 0, v_mat + 1, v_mat + 2);
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 2, v_mat + 1, v_mat + 3);
};
int t = 0;
for (const int curve_i : curves.curves_range()) {
IndexRange points = points_by_curve[curve_i];
const bool is_cyclic = cyclic[curve_i];

Add details about TODO. Something that helps others to pick up a task, or to understand that specific case is not expected to be yet working.

Add details about TODO. Something that helps others to pick up a task, or to understand that specific case is not expected to be yet working.
const int v_start = v;
const int num_triangles = points.size() - 2;
/* First point is not drawn. */
verts[v].mat = -1;
v++;
for (const int tri_i : IndexRange(num_triangles)) {
uint3 tri = drawing.runtime->triangles_cache[t + tri_i];
GPU_indexbuf_add_tri_verts(&ibo,
(v + tri.x) << GP_VERTEX_ID_SHIFT,
(v + tri.y) << GP_VERTEX_ID_SHIFT,
(v + tri.z) << GP_VERTEX_ID_SHIFT);
}
for (const int point_i : points) {
populate_point(curve_i, point_i, v_start, v);
v++;
@ -310,6 +332,8 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
/* Last point is not drawn. */
verts[v].mat = -1;
v++;
t += num_triangles;
}
});

View File

@ -15,14 +15,16 @@
# include "BLI_span.hh"
namespace blender::bke {
class GreasePencilRuntime;
class GreasePencilDrawingRuntime;
namespace gpencil {
class Layer;
}
} // namespace blender::bke
using GreasePencilRuntimeHandle = blender::bke::GreasePencilRuntime;
using GreasePencilDrawingRuntimeHandle = blender::bke::GreasePencilDrawingRuntime;
#else
typedef struct GreasePencilLayerRuntimeHandle GreasePencilLayerRuntimeHandle;
typedef struct GreasePencilRuntimeHandle GreasePencilRuntimeHandle;
typedef struct GreasePencilDrawingRuntimeHandle GreasePencilDrawingRuntimeHandle;
#endif
#ifdef __cplusplus
@ -61,6 +63,10 @@ typedef struct GreasePencilDrawing {
* The stroke data for this drawing.
*/
CurvesGeometry geometry;
/**
* Runtime data on the drawing.
*/
GreasePencilDrawingRuntimeHandle *runtime;
filedescriptor marked this conversation as resolved Outdated

Move below runtime data pointer.

Move below runtime data pointer.
} GreasePencilDrawing;
typedef struct GreasePencilDrawingReference {