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
4 changed files with 127 additions and 3 deletions
Showing only changes of commit f49427d182 - Show all commits

View File

@ -82,6 +82,17 @@ class TreeNode : public ::GreasePencilLayerTreeNode, NonMovable {
Layer &as_layer_for_write();
};
/**
Review

The _for_write() suffix doesn't seem super helpful here TBH, but I guess it doesn't hurt.

The `_for_write()` suffix doesn't seem super helpful here TBH, but I guess it doesn't hurt.
* A layer mask stores a reference to a layer that will mask other layers.
*/
class LayerMask : public ::GreasePencilLayerMask {
public:
LayerMask();
explicit LayerMask(StringRefNull name);
LayerMask(const LayerMask &other);
~LayerMask();
};
/**
* A layer maps drawings to scene frames. It can be thought of as one independent channel in the
* timeline.
@ -114,7 +125,15 @@ class Layer : public TreeNode, public ::GreasePencilLayer {
* drawings, then the last referenced drawing is held for the rest of the duration.
*/
Map<int, GreasePencilFrame> frames_;
/**
* Caches a sorted vector of the keys of `frames_`.
*/
mutable SharedCache<Vector<int>> sorted_keys_cache_;
/**
* A vector of LayerMask. This layer will be masked by the layers referenced in the masks.
* A layer can have zero or more layer masks.
*/
Vector<LayerMask> masks_;
public:
Layer();
@ -128,6 +147,12 @@ class Layer : public TreeNode, public ::GreasePencilLayer {
const Map<int, GreasePencilFrame> &frames() const;
Map<int, GreasePencilFrame> &frames_for_write();
/**
* \returns the layer masks.
*/
const Vector<LayerMask> &masks() const;
Vector<LayerMask> &masks_for_write();
/**

Better to return a span here maybe?

Better to return a span here maybe?
* Inserts the frame into the layer. Fails if there exists a frame at \a frame_number already.
* \returns true on success.

View File

@ -298,19 +298,45 @@ Layer &TreeNode::as_layer_for_write()
return *static_cast<Layer *>(this);
}
Layer::Layer() : TreeNode::TreeNode(GP_LAYER_TREE_LEAF), frames_()
LayerMask::LayerMask()
{
this->layer_name = nullptr;
}
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(...)`.
LayerMask::LayerMask(StringRefNull name)
{
this->layer_name = BLI_strdup(name.c_str());
}
LayerMask::LayerMask(const LayerMask &other) : LayerMask()
{
if (other.layer_name) {
this->layer_name = BLI_strdup(other.layer_name);
}
}
LayerMask::~LayerMask()
{
if (this->layer_name) {
MEM_freeN(this->layer_name);
}
}
Layer::Layer() : TreeNode::TreeNode(GP_LAYER_TREE_LEAF), frames_(), masks_()
{
this->parsubstr = nullptr;
this->viewlayer_name = nullptr;
}
Layer::Layer(StringRefNull name) : TreeNode::TreeNode(GP_LAYER_TREE_LEAF, name), frames_()
Layer::Layer(StringRefNull name)
: TreeNode::TreeNode(GP_LAYER_TREE_LEAF, name), frames_(), masks_()
{
this->parsubstr = nullptr;
this->viewlayer_name = nullptr;
}
Layer::Layer(const Layer &other) : TreeNode::TreeNode(other), frames_(other.frames_)
Layer::Layer(const Layer &other)
: TreeNode::TreeNode(other), frames_(other.frames_), masks_(other.masks_)
{
this->parsubstr = nullptr;
this->viewlayer_name = nullptr;
@ -343,6 +369,16 @@ Map<int, GreasePencilFrame> &Layer::frames_for_write()
return this->frames_;
}
const Vector<LayerMask> &Layer::masks() const
{
return this->masks_;
}
Vector<LayerMask> &Layer::masks_for_write()
{
return this->masks_;
}
bool Layer::insert_frame(int frame_number, GreasePencilFrame &frame)
{
this->sorted_keys_cache_.tag_dirty();
@ -1094,6 +1130,13 @@ static void save_layer_to_storage(const blender::bke::greasepencil::Layer &node,
if (node.viewlayer_name) {
new_leaf->layer.viewlayer_name = BLI_strdup(node.viewlayer_name);
}
BLI_listbase_clear(&new_leaf->layer.masks_storage);
for (const bke::greasepencil::LayerMask &mask : node.masks()) {
GreasePencilLayerMask *new_mask = MEM_cnew<GreasePencilLayerMask>(__func__);
new_mask->layer_name = BLI_strdup(mask.layer_name);
new_mask->flag = mask.flag;
BLI_addtail(&new_leaf->layer.masks_storage, new_mask);
}
new_leaf->layer.opacity = node.opacity;
copy_v4_v4(new_leaf->layer.tint_color, node.tint_color);
copy_v3_v3(new_leaf->layer.location, node.location);
@ -1162,6 +1205,12 @@ static void read_layer_from_storage(blender::bke::greasepencil::LayerGroup &curr
if (node_leaf->layer.viewlayer_name) {
new_layer.viewlayer_name = BLI_strdup(node_leaf->layer.viewlayer_name);
}
Vector<LayerMask> masks = new_layer.masks_for_write();
LISTBASE_FOREACH (bGPDlayer_Mask *, mask, &node_leaf->layer.masks_storage) {
LayerMask new_mask = LayerMask(mask->name);
new_mask.flag = mask->flag;
masks.append(std::move(new_mask));
}
new_layer.opacity = node_leaf->layer.opacity;
copy_v4_v4(new_layer.tint_color, node_leaf->layer.tint_color);
copy_v3_v3(new_layer.location, node_leaf->layer.location);
@ -1236,6 +1285,10 @@ void GreasePencil::read_layer_tree_storage(BlendDataReader *reader)
BLO_read_data_address(reader, &node_leaf->layer.frames_storage.values);
BLO_read_data_address(reader, &node_leaf->layer.parsubstr);
BLO_read_data_address(reader, &node_leaf->layer.viewlayer_name);
BLO_read_list(reader, &node_leaf->layer.masks_storage);
LISTBASE_FOREACH (GreasePencilLayerMask *, mask, &node_leaf->layer.masks_storage) {
BLO_read_data_address(reader, &mask->layer_name);
}
break;
}
case GP_LAYER_TREE_GROUP: {
@ -1267,6 +1320,10 @@ void GreasePencil::write_layer_tree_storage(BlendWriter *writer)
node_leaf->layer.frames_storage.values);
BLO_write_string(writer, node_leaf->layer.parsubstr);
BLO_write_string(writer, node_leaf->layer.viewlayer_name);
BLO_write_struct_list(writer, GreasePencilLayerMask, &node_leaf->layer.masks_storage);
LISTBASE_FOREACH (GreasePencilLayerMask *, mask, &node_leaf->layer.masks_storage) {
BLO_write_string(writer, mask->layer_name);
}
break;
}
case GP_LAYER_TREE_GROUP: {
@ -1302,6 +1359,12 @@ void GreasePencil::free_layer_tree_storage()
if (node_leaf->layer.viewlayer_name) {
MEM_freeN(node_leaf->layer.viewlayer_name);
}
LISTBASE_FOREACH_MUTABLE (GreasePencilLayerMask *, mask, &node_leaf->layer.masks_storage) {
if (mask->layer_name) {
MEM_freeN(mask->layer_name);
}
MEM_freeN(mask);
}
MEM_freeN(node_leaf);
break;
}

View File

@ -219,6 +219,13 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b
if (viewlayername_len > 0) {
new_layer.viewlayer_name = BLI_strdupn(gpl->viewlayername, viewlayername_len);
}
/* Convert the layer masks. */
Vector<LayerMask> masks = new_layer.masks_for_write();
LISTBASE_FOREACH (bGPDlayer_Mask *, mask, &gpl->mask_layers) {
LayerMask new_mask = LayerMask(mask->name);
new_mask.flag = mask->flag;
masks.append(std::move(new_mask));
}
new_layer.opacity = gpl->opacity;
copy_v4_v4(new_layer.tint_color, gpl->tintcolor);
copy_v3_v3(new_layer.location, gpl->location);

View File

@ -139,6 +139,31 @@ typedef struct GreasePencilLayerFramesMapStorage {
char _pad[4];
} GreasePencilLayerFramesMapStorage;
/**
* Flag for layer masks. #GreasePencilLayerMask.flag
*/
typedef enum GreasePencilLayerMaskFlag {
GP_LAYER_MASK_HIDE = (1 << 0),
GP_LAYER_MASK_INVERT = (1 << 1),
} GreasePencilLayerMaskFlag;
/**
* A grease pencil layer mask stores the name of a layer that is the mask.
*/
typedef struct GreasePencilLayerMask {
struct GreasePencilLayerMask *next, *prev;
/**
* The name of the layer that is the mask.
* \note Null-terminated.
*/
char *layer_name;
/**
* Layer mask flag. See `GreasePencilLayerMaskFlag`.
*/
uint16_t flag;
char _pad[6];
} GreasePencilLayerMask;
/**
* Type of parent of a layer. #GreasePencilLayer.parent_type
*/
@ -193,6 +218,10 @@ typedef struct GreasePencilLayer {
* \note Null-terminated.
*/
char *viewlayer_name;
/**
* List of `GreasePencilLayerMask`.
*/
ListBase masks_storage;
/**
* Opacity of the layer.
*/