Initial Grease Pencil 3.0 stage #106848
|
@ -443,6 +443,12 @@ void legacy_gpencil_to_grease_pencil(GreasePencil &grease_pencil, bGPdata &gpd);
|
||||||
} // namespace gpencil
|
} // namespace gpencil
|
||||||
|
|
||||||
using namespace blender::bke::gpencil;
|
using namespace blender::bke::gpencil;
|
||||||
|
|
||||||
|
class GreasePencilDrawingRuntime {
|
||||||
|
public:
|
||||||
|
Vector<uint3> triangles_cache;
|
||||||
|
};
|
||||||
|
|
||||||
class GreasePencilRuntime {
|
class GreasePencilRuntime {
|
||||||
private:
|
private:
|
||||||
LayerGroup root_group_;
|
LayerGroup root_group_;
|
||||||
|
@ -467,7 +473,9 @@ class GreasePencilRuntime {
|
||||||
} // namespace blender::bke
|
} // namespace blender::bke
|
||||||
|
|
||||||
struct Main;
|
struct Main;
|
||||||
|
struct Depsgraph;
|
||||||
struct BoundBox;
|
struct BoundBox;
|
||||||
|
|
||||||
void *BKE_grease_pencil_add(Main *bmain, const char *name);
|
void *BKE_grease_pencil_add(Main *bmain, const char *name);
|
||||||
BoundBox *BKE_grease_pencil_boundbox_get(Object *ob);
|
BoundBox *BKE_grease_pencil_boundbox_get(Object *ob);
|
||||||
|
void BKE_grease_pencil_eval_geometry(Depsgraph *depsgraph, GreasePencil &grease_pencil);
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include "BKE_object.h"
|
#include "BKE_object.h"
|
||||||
|
|
||||||
#include "BLI_math_vector_types.hh"
|
#include "BLI_math_vector_types.hh"
|
||||||
|
#include "BLI_memarena.h"
|
||||||
|
#include "BLI_polyfill_2d.h"
|
||||||
#include "BLI_span.hh"
|
#include "BLI_span.hh"
|
||||||
#include "BLI_stack.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;
|
dst_drawing->base.flag = src_drawing->base.flag;
|
||||||
|
|
||||||
new (&dst_drawing->geometry) bke::CurvesGeometry(src_drawing->geometry.wrap());
|
new (&dst_drawing->geometry) bke::CurvesGeometry(src_drawing->geometry.wrap());
|
||||||
|
dst_drawing->runtime = MEM_new<bke::GreasePencilDrawingRuntime>(__func__);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GREASE_PENCIL_DRAWING_REFERENCE: {
|
case GREASE_PENCIL_DRAWING_REFERENCE: {
|
||||||
|
@ -298,6 +301,67 @@ BoundBox *BKE_grease_pencil_boundbox_get(Object *ob)
|
||||||
return ob->runtime.bb;
|
return ob->runtime.bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void grease_pencil_drawing_calculate_fill_triangles(GreasePencilDrawing &drawing)
|
||||||
filedescriptor marked this conversation as resolved
Outdated
|
|||||||
|
{
|
||||||
|
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 */
|
/* Draw Cache */
|
||||||
|
|
||||||
void (*BKE_grease_pencil_batch_cache_dirty_tag_cb)(GreasePencil *grease_pencil,
|
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. */
|
/* Initialize runtime data. */
|
||||||
drawing->geometry.runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__);
|
drawing->geometry.runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__);
|
||||||
drawing->geometry.wrap().update_curve_types();
|
drawing->geometry.wrap().update_curve_types();
|
||||||
|
drawing->runtime = MEM_new<blender::bke::GreasePencilDrawingRuntime>(__func__);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GREASE_PENCIL_DRAWING_REFERENCE: {
|
case GREASE_PENCIL_DRAWING_REFERENCE: {
|
||||||
Hans Goudey
commented
`.as_span()` shouldn't be necessary here.
|
|||||||
|
@ -406,6 +471,7 @@ void GreasePencil::free_drawing_array()
|
||||||
case GREASE_PENCIL_DRAWING: {
|
case GREASE_PENCIL_DRAWING: {
|
||||||
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_or_ref);
|
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_or_ref);
|
||||||
drawing->geometry.wrap().~CurvesGeometry();
|
drawing->geometry.wrap().~CurvesGeometry();
|
||||||
|
MEM_delete(drawing->runtime);
|
||||||
MEM_freeN(drawing);
|
MEM_freeN(drawing);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
#include "BKE_fcurve_driver.h"
|
#include "BKE_fcurve_driver.h"
|
||||||
#include "BKE_gpencil_legacy.h"
|
#include "BKE_gpencil_legacy.h"
|
||||||
#include "BKE_gpencil_modifier_legacy.h"
|
#include "BKE_gpencil_modifier_legacy.h"
|
||||||
|
#include "BKE_grease_pencil.hh"
|
||||||
#include "BKE_idprop.h"
|
#include "BKE_idprop.h"
|
||||||
#include "BKE_idtype.h"
|
#include "BKE_idtype.h"
|
||||||
#include "BKE_image.h"
|
#include "BKE_image.h"
|
||||||
|
@ -1658,8 +1659,13 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_GP: {
|
case ID_GP: {
|
||||||
/* TODO */
|
op_node = add_operation_node(obdata,
|
||||||
op_node = add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
|
NodeType::GEOMETRY,
|
||||||
|
OperationCode::GEOMETRY_EVAL,
|
||||||
|
[obdata_cow](::Depsgraph *depsgraph) {
|
||||||
|
BKE_grease_pencil_eval_geometry(depsgraph,
|
||||||
|
*(GreasePencil *)obdata_cow);
|
||||||
|
});
|
||||||
op_node->set_as_entry();
|
op_node->set_as_entry();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,6 +234,7 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
|
||||||
* vertex.*/
|
* vertex.*/
|
||||||
total_points_num += curves.points_num() + num_cyclic + curves.curves_num() * 2;
|
total_points_num += curves.points_num() + num_cyclic + curves.curves_num() * 2;
|
||||||
total_triangles_num += (curves.points_num() + num_cyclic) * 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;
|
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].point_id = v;
|
||||||
verts[v].stroke_id = v_start;
|
verts[v].stroke_id = v_start;
|
||||||
verts[v].mat = materials[curve_i] % GPENCIL_MATERIAL_BUFFER_LEN;
|
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);
|
verts[v].packed_asp_hard_rot = pack_rotation_aspect_hardness(0.0f, 1.0f, 1.0f);
|
||||||
|
/* TODO */
|
||||||
Hans Goudey
commented
These These `.as_span()` calls shouldn't be necessary
|
|||||||
verts[v].u_stroke = 0;
|
verts[v].u_stroke = 0;
|
||||||
|
/* TODO */
|
||||||
verts[v].uv_fill[0] = verts[v].uv_fill[1] = 0;
|
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;
|
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 + 0, v_mat + 1, v_mat + 2);
|
||||||
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 2, v_mat + 1, v_mat + 3);
|
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()) {
|
for (const int curve_i : curves.curves_range()) {
|
||||||
IndexRange points = points_by_curve[curve_i];
|
IndexRange points = points_by_curve[curve_i];
|
||||||
const bool is_cyclic = cyclic[curve_i];
|
const bool is_cyclic = cyclic[curve_i];
|
||||||
Sergey Sharybin
commented
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 v_start = v;
|
||||||
|
const int num_triangles = points.size() - 2;
|
||||||
|
|
||||||
/* First point is not drawn. */
|
/* First point is not drawn. */
|
||||||
verts[v].mat = -1;
|
verts[v].mat = -1;
|
||||||
v++;
|
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) {
|
for (const int point_i : points) {
|
||||||
populate_point(curve_i, point_i, v_start, v);
|
populate_point(curve_i, point_i, v_start, v);
|
||||||
v++;
|
v++;
|
||||||
|
@ -310,6 +332,8 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
|
||||||
/* Last point is not drawn. */
|
/* Last point is not drawn. */
|
||||||
verts[v].mat = -1;
|
verts[v].mat = -1;
|
||||||
v++;
|
v++;
|
||||||
|
|
||||||
|
t += num_triangles;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,16 @@
|
||||||
# include "BLI_span.hh"
|
# include "BLI_span.hh"
|
||||||
namespace blender::bke {
|
namespace blender::bke {
|
||||||
class GreasePencilRuntime;
|
class GreasePencilRuntime;
|
||||||
|
class GreasePencilDrawingRuntime;
|
||||||
namespace gpencil {
|
namespace gpencil {
|
||||||
class Layer;
|
class Layer;
|
||||||
}
|
}
|
||||||
} // namespace blender::bke
|
} // namespace blender::bke
|
||||||
using GreasePencilRuntimeHandle = blender::bke::GreasePencilRuntime;
|
using GreasePencilRuntimeHandle = blender::bke::GreasePencilRuntime;
|
||||||
|
using GreasePencilDrawingRuntimeHandle = blender::bke::GreasePencilDrawingRuntime;
|
||||||
#else
|
#else
|
||||||
typedef struct GreasePencilLayerRuntimeHandle GreasePencilLayerRuntimeHandle;
|
|
||||||
typedef struct GreasePencilRuntimeHandle GreasePencilRuntimeHandle;
|
typedef struct GreasePencilRuntimeHandle GreasePencilRuntimeHandle;
|
||||||
|
typedef struct GreasePencilDrawingRuntimeHandle GreasePencilDrawingRuntimeHandle;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -61,6 +63,10 @@ typedef struct GreasePencilDrawing {
|
||||||
* The stroke data for this drawing.
|
* The stroke data for this drawing.
|
||||||
*/
|
*/
|
||||||
CurvesGeometry geometry;
|
CurvesGeometry geometry;
|
||||||
|
/**
|
||||||
|
* Runtime data on the drawing.
|
||||||
|
*/
|
||||||
|
GreasePencilDrawingRuntimeHandle *runtime;
|
||||||
filedescriptor marked this conversation as resolved
Outdated
Falk David
commented
Move below runtime data pointer. Move below runtime data pointer.
|
|||||||
} GreasePencilDrawing;
|
} GreasePencilDrawing;
|
||||||
|
|
||||||
typedef struct GreasePencilDrawingReference {
|
typedef struct GreasePencilDrawingReference {
|
||||||
|
|
Loading…
Reference in New Issue
Make sure to not overwrite
min
andmax
but account any value already present. E.g. usemath::min_max(...)
.