Refactor: GPv3: legacy_gpencil_to_grease_pencil
This is part of #121565. Refactors `legacy_gpencil_to_grease_pencil` to use `GreasePencil::insert_frame` instead of manually creating the drawing array. Now `legacy_gpencil_frame_to_grease_pencil_drawing` actually returns a drawing by value. Note: This means that we're now resizing the drawing array for every frame in every layer, but this can be optimized later.
This commit is contained in:
@@ -71,6 +71,9 @@ class Drawing : public ::GreasePencilDrawing {
|
||||
public:
|
||||
Drawing();
|
||||
Drawing(const Drawing &other);
|
||||
Drawing &operator=(const Drawing &other);
|
||||
Drawing(Drawing &&other);
|
||||
Drawing &operator=(Drawing &&other);
|
||||
~Drawing();
|
||||
|
||||
const bke::CurvesGeometry &strokes() const;
|
||||
|
||||
@@ -315,6 +315,39 @@ Drawing::Drawing(const Drawing &other)
|
||||
this->runtime->curve_texture_matrices = other.runtime->curve_texture_matrices;
|
||||
}
|
||||
|
||||
Drawing &Drawing::operator=(const Drawing &other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
std::destroy_at(this);
|
||||
new (this) Drawing(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Drawing::Drawing(Drawing &&other)
|
||||
{
|
||||
this->base.type = GP_DRAWING;
|
||||
other.base.type = GP_DRAWING;
|
||||
this->base.flag = other.base.flag;
|
||||
other.base.flag = 0;
|
||||
|
||||
new (&this->geometry) bke::CurvesGeometry(std::move(other.geometry.wrap()));
|
||||
|
||||
this->runtime = other.runtime;
|
||||
other.runtime = nullptr;
|
||||
}
|
||||
|
||||
Drawing &Drawing::operator=(Drawing &&other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
std::destroy_at(this);
|
||||
new (this) Drawing(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Drawing::~Drawing()
|
||||
{
|
||||
this->strokes().~CurvesGeometry();
|
||||
|
||||
@@ -665,14 +665,11 @@ static blender::float4x2 get_legacy_texture_matrix(bGPDstroke *gps)
|
||||
return texture_matrix * strokemat4x3;
|
||||
}
|
||||
|
||||
static void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
const ListBase &vertex_group_names,
|
||||
GreasePencilDrawing &r_drawing)
|
||||
static Drawing legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
const ListBase &vertex_group_names)
|
||||
{
|
||||
/* Construct an empty CurvesGeometry in-place. */
|
||||
new (&r_drawing.geometry) CurvesGeometry();
|
||||
r_drawing.base.type = GP_DRAWING;
|
||||
r_drawing.runtime = MEM_new<bke::greasepencil::DrawingRuntime>(__func__);
|
||||
/* Create a new empty drawing. */
|
||||
Drawing drawing;
|
||||
|
||||
/* Get the number of points, number of strokes and the offsets for each stroke. */
|
||||
Vector<int> offsets;
|
||||
@@ -703,11 +700,10 @@ static void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
|
||||
/* Return if the legacy frame contains no strokes (or zero points). */
|
||||
if (num_strokes == 0) {
|
||||
return;
|
||||
return drawing;
|
||||
}
|
||||
|
||||
/* Resize the CurvesGeometry. */
|
||||
Drawing &drawing = r_drawing.wrap();
|
||||
CurvesGeometry &curves = drawing.strokes_for_write();
|
||||
curves.resize(num_points, num_strokes);
|
||||
curves.offsets_for_write().copy_from(offsets);
|
||||
@@ -904,6 +900,8 @@ static void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
stroke_hardnesses.finish();
|
||||
stroke_point_aspect_ratios.finish();
|
||||
stroke_materials.finish();
|
||||
|
||||
return drawing;
|
||||
}
|
||||
|
||||
static void legacy_gpencil_to_grease_pencil(ConversionData &conversion_data,
|
||||
@@ -930,16 +928,7 @@ static void legacy_gpencil_to_grease_pencil(ConversionData &conversion_data,
|
||||
SET_FLAG_FROM_TEST(
|
||||
grease_pencil.flag, (gpd.draw_mode == GP_DRAWMODE_3D), GREASE_PENCIL_STROKE_ORDER_3D);
|
||||
|
||||
int num_drawings = 0;
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd.layers) {
|
||||
num_drawings += BLI_listbase_count(&gpl->frames);
|
||||
}
|
||||
|
||||
grease_pencil.drawing_array_num = num_drawings;
|
||||
grease_pencil.drawing_array = reinterpret_cast<GreasePencilDrawingBase **>(
|
||||
MEM_cnew_array<GreasePencilDrawing *>(num_drawings, __func__));
|
||||
|
||||
int i = 0, layer_idx = 0;
|
||||
int layer_idx = 0;
|
||||
LISTBASE_FOREACH_INDEX (bGPDlayer *, gpl, &gpd.layers, layer_idx) {
|
||||
/* Create a new layer. */
|
||||
Layer &new_layer = grease_pencil.add_layer(
|
||||
@@ -984,28 +973,25 @@ static void legacy_gpencil_to_grease_pencil(ConversionData &conversion_data,
|
||||
new_layer.opacity = gpl->opacity;
|
||||
|
||||
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
|
||||
grease_pencil.drawing_array[i] = reinterpret_cast<GreasePencilDrawingBase *>(
|
||||
MEM_new<GreasePencilDrawing>(__func__));
|
||||
GreasePencilDrawing &drawing = *reinterpret_cast<GreasePencilDrawing *>(
|
||||
grease_pencil.drawing_array[i]);
|
||||
|
||||
/* Convert the frame to a drawing. */
|
||||
legacy_gpencil_frame_to_grease_pencil_drawing(*gpf, gpd.vertex_group_names, drawing);
|
||||
|
||||
/* Add the frame to the layer. */
|
||||
if (GreasePencilFrame *new_frame = new_layer.add_frame(gpf->framenum)) {
|
||||
new_frame->drawing_index = i;
|
||||
new_frame->type = gpf->key_type;
|
||||
SET_FLAG_FROM_TEST(new_frame->flag, (gpf->flag & GP_FRAME_SELECT), GP_FRAME_SELECTED);
|
||||
Drawing *dst_drawing = grease_pencil.insert_frame(
|
||||
new_layer, gpf->framenum, 0, eBezTriple_KeyframeType(gpf->key_type));
|
||||
if (dst_drawing == nullptr) {
|
||||
/* Might fail because GPv2 technically allowed overlapping keyframes on the same frame
|
||||
* (very unlikely to occur in real world files). In GPv3, keyframes always have to be on
|
||||
* different frames. In this case we can't create a keyframe and have to skip it. */
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
/* Convert the frame to a drawing. */
|
||||
*dst_drawing = legacy_gpencil_frame_to_grease_pencil_drawing(*gpf, gpd.vertex_group_names);
|
||||
|
||||
/* This frame was just inserted above, so it should always exist. */
|
||||
GreasePencilFrame &new_frame = *new_layer.frame_at(gpf->framenum);
|
||||
SET_FLAG_FROM_TEST(new_frame.flag, (gpf->flag & GP_FRAME_SELECT), GP_FRAME_SELECTED);
|
||||
}
|
||||
|
||||
if ((gpl->flag & GP_LAYER_ACTIVE) != 0) {
|
||||
grease_pencil.set_active_layer(&new_layer);
|
||||
}
|
||||
|
||||
/* TODO: Update drawing user counts. */
|
||||
}
|
||||
|
||||
/* Second loop, to write to layer attributes after all layers were created. */
|
||||
|
||||
Reference in New Issue
Block a user