GeometrySet: Add new GreasePencilComponent
This is mostly boilerplate code to add a new `GeometryComponent` as well as making sure the new `GeometryComponent::Type` is handled in all the `switch` statements. Pull Request: https://projects.blender.org/blender/blender/pulls/110457
This commit is contained in:
@@ -22,10 +22,11 @@ struct Curve;
|
||||
struct Mesh;
|
||||
struct PointCloud;
|
||||
struct Volume;
|
||||
struct GreasePencil;
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
#define GEO_COMPONENT_TYPE_ENUM_SIZE 6
|
||||
#define GEO_COMPONENT_TYPE_ENUM_SIZE 7
|
||||
|
||||
enum class GeometryOwnershipType {
|
||||
/* The geometry is owned. This implies that it can be changed. */
|
||||
@@ -63,6 +64,7 @@ class GeometryComponent : public ImplicitSharingMixin {
|
||||
Volume = 3,
|
||||
Curve = 4,
|
||||
Edit = 5,
|
||||
GreasePencil = 6,
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -120,6 +122,7 @@ inline constexpr bool is_geometry_component_v = std::is_base_of_v<GeometryCompon
|
||||
* - #PointCloudComponent
|
||||
* - #InstancesComponent
|
||||
* - #VolumeComponent
|
||||
* - #GreasePencilComponent
|
||||
*
|
||||
* Copying a geometry set is a relatively cheap operation, because it does not copy the referenced
|
||||
* geometry components, so #GeometrySet can often be passed or moved by value.
|
||||
@@ -266,6 +269,11 @@ struct GeometrySet {
|
||||
*/
|
||||
static GeometrySet create_with_instances(
|
||||
Instances *instances, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
|
||||
/**
|
||||
* Create a new geometry set that only contains the given Grease Pencil data.
|
||||
*/
|
||||
static GeometrySet create_with_grease_pencil(
|
||||
GreasePencil *grease_pencil, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
|
||||
|
||||
/* Utility methods for access. */
|
||||
/**
|
||||
@@ -292,6 +300,10 @@ struct GeometrySet {
|
||||
* Returns true when the geometry set has any data that is not an instance.
|
||||
*/
|
||||
bool has_realized_data() const;
|
||||
/**
|
||||
* Returns true when the geometry set has a Grease Pencil component that has grease pencil data.
|
||||
*/
|
||||
bool has_grease_pencil() const;
|
||||
/**
|
||||
* Return true if the geometry set has any component that isn't empty.
|
||||
*/
|
||||
@@ -321,6 +333,10 @@ struct GeometrySet {
|
||||
* Returns read-only curve edit hints or null.
|
||||
*/
|
||||
const CurvesEditHints *get_curve_edit_hints_for_read() const;
|
||||
/**
|
||||
* Returns a read-only Grease Pencil data-block or null.
|
||||
*/
|
||||
const GreasePencil *get_grease_pencil_for_read() const;
|
||||
|
||||
/**
|
||||
* Returns a mutable mesh or null. No ownership is transferred.
|
||||
@@ -346,6 +362,10 @@ struct GeometrySet {
|
||||
* Returns mutable curve edit hints or null.
|
||||
*/
|
||||
CurvesEditHints *get_curve_edit_hints_for_write();
|
||||
/**
|
||||
* Returns a mutable Grease Pencil data-block or null. No ownership is transferred.
|
||||
*/
|
||||
GreasePencil *get_grease_pencil_for_write();
|
||||
|
||||
/* Utility methods for replacement. */
|
||||
/**
|
||||
@@ -372,6 +392,11 @@ struct GeometrySet {
|
||||
*/
|
||||
void replace_instances(Instances *instances,
|
||||
GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
|
||||
/**
|
||||
* Clear the existing Grease Pencil data-block and replace it with the given one.
|
||||
*/
|
||||
void replace_grease_pencil(GreasePencil *grease_pencil,
|
||||
GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -655,4 +680,43 @@ class GeometryComponentEditData final : public GeometryComponent {
|
||||
static constexpr inline GeometryComponent::Type static_type = GeometryComponent::Type::Edit;
|
||||
};
|
||||
|
||||
/**
|
||||
* A geometry component that stores #GreasePencil data.
|
||||
* This component does not implement an attribute API, because the #GreasePencil data itself does
|
||||
* not store any attributes, only the individual drawings within it.
|
||||
*/
|
||||
class GreasePencilComponent : public GeometryComponent {
|
||||
private:
|
||||
GreasePencil *grease_pencil_ = nullptr;
|
||||
GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
|
||||
|
||||
public:
|
||||
GreasePencilComponent();
|
||||
~GreasePencilComponent();
|
||||
GeometryComponent *copy() const override;
|
||||
|
||||
void clear() override;
|
||||
bool has_grease_pencil() const;
|
||||
/**
|
||||
* Clear the component and replace it with the new \a grease_pencil data.
|
||||
*/
|
||||
void replace(GreasePencil *grease_pencil,
|
||||
GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
|
||||
/**
|
||||
* Return the Grease Pencil data and clear the component. The caller takes over responsibility
|
||||
* for freeing the Grease Pencil data (if the component was responsible before).
|
||||
*/
|
||||
GreasePencil *release();
|
||||
|
||||
const GreasePencil *get_for_read() const;
|
||||
GreasePencil *get_for_write();
|
||||
|
||||
bool is_empty() const final;
|
||||
|
||||
bool owns_direct_data() const override;
|
||||
void ensure_owns_direct_data() override;
|
||||
|
||||
static constexpr inline GeometryComponent::Type static_type = Type::GreasePencil;
|
||||
};
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
@@ -542,6 +542,7 @@ inline bool GreasePencil::has_active_layer() const
|
||||
|
||||
void *BKE_grease_pencil_add(Main *bmain, const char *name);
|
||||
GreasePencil *BKE_grease_pencil_new_nomain();
|
||||
GreasePencil *BKE_grease_pencil_copy_for_eval(const GreasePencil *grease_pencil_src);
|
||||
BoundBox *BKE_grease_pencil_boundbox_get(Object *ob);
|
||||
void BKE_grease_pencil_data_update(struct Depsgraph *depsgraph,
|
||||
struct Scene *scene,
|
||||
|
||||
@@ -133,6 +133,7 @@ set(SRC
|
||||
intern/freestyle.cc
|
||||
intern/geometry_component_curves.cc
|
||||
intern/geometry_component_edit_data.cc
|
||||
intern/geometry_component_grease_pencil.cc
|
||||
intern/geometry_component_instances.cc
|
||||
intern/geometry_component_mesh.cc
|
||||
intern/geometry_component_pointcloud.cc
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_lib_id.h"
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Geometry Component Implementation
|
||||
* \{ */
|
||||
|
||||
GreasePencilComponent::GreasePencilComponent() : GeometryComponent(Type::GreasePencil) {}
|
||||
|
||||
GreasePencilComponent::~GreasePencilComponent()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
GeometryComponent *GreasePencilComponent::copy() const
|
||||
{
|
||||
GreasePencilComponent *new_component = new GreasePencilComponent();
|
||||
if (grease_pencil_ != nullptr) {
|
||||
new_component->grease_pencil_ = BKE_grease_pencil_copy_for_eval(grease_pencil_);
|
||||
new_component->ownership_ = GeometryOwnershipType::Owned;
|
||||
}
|
||||
return new_component;
|
||||
}
|
||||
|
||||
void GreasePencilComponent::clear()
|
||||
{
|
||||
BLI_assert(this->is_mutable() || this->is_expired());
|
||||
if (grease_pencil_ != nullptr) {
|
||||
if (ownership_ == GeometryOwnershipType::Owned) {
|
||||
BKE_id_free(nullptr, grease_pencil_);
|
||||
}
|
||||
grease_pencil_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool GreasePencilComponent::has_grease_pencil() const
|
||||
{
|
||||
return grease_pencil_ != nullptr;
|
||||
}
|
||||
|
||||
void GreasePencilComponent::replace(GreasePencil *grease_pencil, GeometryOwnershipType ownership)
|
||||
{
|
||||
BLI_assert(this->is_mutable());
|
||||
this->clear();
|
||||
grease_pencil_ = grease_pencil;
|
||||
ownership_ = ownership;
|
||||
}
|
||||
|
||||
GreasePencil *GreasePencilComponent::release()
|
||||
{
|
||||
BLI_assert(this->is_mutable());
|
||||
GreasePencil *grease_pencil = grease_pencil_;
|
||||
grease_pencil_ = nullptr;
|
||||
return grease_pencil;
|
||||
}
|
||||
|
||||
const GreasePencil *GreasePencilComponent::get_for_read() const
|
||||
{
|
||||
return grease_pencil_;
|
||||
}
|
||||
|
||||
GreasePencil *GreasePencilComponent::get_for_write()
|
||||
{
|
||||
BLI_assert(this->is_mutable());
|
||||
if (ownership_ == GeometryOwnershipType::ReadOnly) {
|
||||
grease_pencil_ = BKE_grease_pencil_copy_for_eval(grease_pencil_);
|
||||
ownership_ = GeometryOwnershipType::Owned;
|
||||
}
|
||||
return grease_pencil_;
|
||||
}
|
||||
|
||||
bool GreasePencilComponent::is_empty() const
|
||||
{
|
||||
return grease_pencil_ == nullptr;
|
||||
}
|
||||
|
||||
bool GreasePencilComponent::owns_direct_data() const
|
||||
{
|
||||
return ownership_ == GeometryOwnershipType::Owned;
|
||||
}
|
||||
|
||||
void GreasePencilComponent::ensure_owns_direct_data()
|
||||
{
|
||||
BLI_assert(this->is_mutable());
|
||||
if (ownership_ != GeometryOwnershipType::Owned) {
|
||||
grease_pencil_ = BKE_grease_pencil_copy_for_eval(grease_pencil_);
|
||||
ownership_ = GeometryOwnershipType::Owned;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
@@ -76,6 +76,7 @@ GeometryFieldContext::GeometryFieldContext(const GeometryComponent &component,
|
||||
}
|
||||
case GeometryComponent::Type::Volume:
|
||||
case GeometryComponent::Type::Edit:
|
||||
case GeometryComponent::Type::GreasePencil:
|
||||
BLI_assert_unreachable();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ GeometryComponentPtr GeometryComponent::create(Type component_type)
|
||||
return new CurveComponent();
|
||||
case Type::Edit:
|
||||
return new GeometryComponentEditData();
|
||||
case Type::GreasePencil:
|
||||
return new GreasePencilComponent();
|
||||
}
|
||||
BLI_assert_unreachable();
|
||||
return {};
|
||||
@@ -344,6 +346,12 @@ const CurvesEditHints *GeometrySet::get_curve_edit_hints_for_read() const
|
||||
return (component == nullptr) ? nullptr : component->curves_edit_hints_.get();
|
||||
}
|
||||
|
||||
const GreasePencil *GeometrySet::get_grease_pencil_for_read() const
|
||||
{
|
||||
const GreasePencilComponent *component = this->get_component_for_read<GreasePencilComponent>();
|
||||
return (component == nullptr) ? nullptr : component->get_for_read();
|
||||
}
|
||||
|
||||
bool GeometrySet::has_pointcloud() const
|
||||
{
|
||||
const PointCloudComponent *component = this->get_component_for_read<PointCloudComponent>();
|
||||
@@ -381,10 +389,16 @@ bool GeometrySet::has_realized_data() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GeometrySet::has_grease_pencil() const
|
||||
{
|
||||
const GreasePencilComponent *component = this->get_component_for_read<GreasePencilComponent>();
|
||||
return component != nullptr && component->has_grease_pencil();
|
||||
}
|
||||
|
||||
bool GeometrySet::is_empty() const
|
||||
{
|
||||
return !(this->has_mesh() || this->has_curves() || this->has_pointcloud() ||
|
||||
this->has_volume() || this->has_instances());
|
||||
this->has_volume() || this->has_instances() || this->has_grease_pencil());
|
||||
}
|
||||
|
||||
GeometrySet GeometrySet::create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership)
|
||||
@@ -424,6 +438,14 @@ GeometrySet GeometrySet::create_with_instances(Instances *instances,
|
||||
return geometry_set;
|
||||
}
|
||||
|
||||
GeometrySet GeometrySet::create_with_grease_pencil(GreasePencil *grease_pencil,
|
||||
GeometryOwnershipType ownership)
|
||||
{
|
||||
GeometrySet geometry_set;
|
||||
geometry_set.replace_grease_pencil(grease_pencil, ownership);
|
||||
return geometry_set;
|
||||
}
|
||||
|
||||
void GeometrySet::replace_mesh(Mesh *mesh, GeometryOwnershipType ownership)
|
||||
{
|
||||
if (mesh == nullptr) {
|
||||
@@ -494,6 +516,21 @@ void GeometrySet::replace_volume(Volume *volume, GeometryOwnershipType ownership
|
||||
component.replace(volume, ownership);
|
||||
}
|
||||
|
||||
void GeometrySet::replace_grease_pencil(GreasePencil *grease_pencil,
|
||||
GeometryOwnershipType ownership)
|
||||
{
|
||||
if (grease_pencil == nullptr) {
|
||||
this->remove<GreasePencilComponent>();
|
||||
return;
|
||||
}
|
||||
if (grease_pencil == this->get_grease_pencil_for_read()) {
|
||||
return;
|
||||
}
|
||||
this->remove<GreasePencilComponent>();
|
||||
GreasePencilComponent &component = this->get_component_for_write<GreasePencilComponent>();
|
||||
component.replace(grease_pencil, ownership);
|
||||
}
|
||||
|
||||
Mesh *GeometrySet::get_mesh_for_write()
|
||||
{
|
||||
MeshComponent *component = this->get_component_ptr<MeshComponent>();
|
||||
@@ -534,6 +571,12 @@ CurvesEditHints *GeometrySet::get_curve_edit_hints_for_write()
|
||||
return component.curves_edit_hints_.get();
|
||||
}
|
||||
|
||||
GreasePencil *GeometrySet::get_grease_pencil_for_write()
|
||||
{
|
||||
GreasePencilComponent *component = this->get_component_ptr<GreasePencilComponent>();
|
||||
return component == nullptr ? nullptr : component->get_for_write();
|
||||
}
|
||||
|
||||
void GeometrySet::attribute_foreach(const Span<GeometryComponent::Type> component_types,
|
||||
const bool include_instances,
|
||||
const AttributeForeachCallback callback) const
|
||||
@@ -709,6 +752,9 @@ bool object_has_geometry_set_instances(const Object &object)
|
||||
break;
|
||||
case GeometryComponent::Type::Edit:
|
||||
break;
|
||||
case GeometryComponent::Type::GreasePencil:
|
||||
is_instance = object.type != OB_GREASE_PENCIL;
|
||||
break;
|
||||
}
|
||||
if (is_instance) {
|
||||
return true;
|
||||
|
||||
@@ -1044,6 +1044,12 @@ GreasePencil *BKE_grease_pencil_new_nomain()
|
||||
return grease_pencil;
|
||||
}
|
||||
|
||||
GreasePencil *BKE_grease_pencil_copy_for_eval(const GreasePencil *grease_pencil_src)
|
||||
{
|
||||
return reinterpret_cast<GreasePencil *>(
|
||||
BKE_id_copy_ex(nullptr, &grease_pencil_src->id, nullptr, LIB_ID_COPY_LOCALIZE));
|
||||
}
|
||||
|
||||
BoundBox *BKE_grease_pencil_boundbox_get(Object *ob)
|
||||
{
|
||||
using namespace blender;
|
||||
|
||||
@@ -985,6 +985,10 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn
|
||||
}
|
||||
break;
|
||||
}
|
||||
case bke::GeometryComponent::Type::GreasePencil: {
|
||||
/* TODO. Do nothing for now. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (type != component_types.last()) {
|
||||
ss << ".\n";
|
||||
@@ -1038,6 +1042,10 @@ static void create_inspection_string_for_geometry_socket(std::stringstream &ss,
|
||||
case bke::GeometryComponent::Type::Edit: {
|
||||
break;
|
||||
}
|
||||
case bke::GeometryComponent::Type::GreasePencil: {
|
||||
ss << TIP_("Grease Pencil");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (type != supported_types.last()) {
|
||||
ss << ", ";
|
||||
|
||||
@@ -627,6 +627,10 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case bke::GeometryComponent::Type::GreasePencil: {
|
||||
/* TODO. Do nothing for now. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,10 @@ GeometryInfoLog::GeometryInfoLog(const bke::GeometrySet &geometry_set)
|
||||
case bke::GeometryComponent::Type::Volume: {
|
||||
break;
|
||||
}
|
||||
case bke::GeometryComponent::Type::GreasePencil: {
|
||||
/* TODO. Do nothing for now. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,10 @@ void GeoNodeExecParams::check_input_geometry_set(StringRef identifier,
|
||||
case GeometryComponent::Type::Edit: {
|
||||
continue;
|
||||
}
|
||||
case GeometryComponent::Type::GreasePencil: {
|
||||
message += TIP_("Grease Pencil");
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->error_message_add(NodeWarningType::Info, std::move(message));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user