WIP: Brush assets project #106303
|
@ -6,6 +6,8 @@
|
||||||
* \ingroup bke
|
* \ingroup bke
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "DNA_brush_types.h"
|
#include "DNA_brush_types.h"
|
||||||
|
@ -24,12 +26,14 @@
|
||||||
|
|
||||||
#include "BLT_translation.h"
|
#include "BLT_translation.h"
|
||||||
|
|
||||||
|
#include "BKE_asset.hh"
|
||||||
#include "BKE_blendfile_link_append.hh"
|
#include "BKE_blendfile_link_append.hh"
|
||||||
#include "BKE_bpath.h"
|
#include "BKE_bpath.h"
|
||||||
#include "BKE_brush.hh"
|
#include "BKE_brush.hh"
|
||||||
#include "BKE_colortools.hh"
|
#include "BKE_colortools.hh"
|
||||||
#include "BKE_context.hh"
|
#include "BKE_context.hh"
|
||||||
#include "BKE_gpencil_legacy.h"
|
#include "BKE_gpencil_legacy.h"
|
||||||
|
#include "BKE_idprop.hh"
|
||||||
#include "BKE_idtype.h"
|
#include "BKE_idtype.h"
|
||||||
#include "BKE_lib_id.hh"
|
#include "BKE_lib_id.hh"
|
||||||
#include "BKE_lib_query.h"
|
#include "BKE_lib_query.h"
|
||||||
|
@ -382,6 +386,39 @@ static void brush_blend_read_after_liblink(BlendLibReader * /*reader*/, ID *id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void brush_asset_metadata_ensure(void *asset_ptr, AssetMetaData *asset_data)
|
||||||
|
{
|
||||||
|
using namespace blender;
|
||||||
|
using namespace blender::bke;
|
||||||
|
|
||||||
|
Brush *brush = reinterpret_cast<Brush *>(asset_ptr);
|
||||||
|
BLI_assert(GS(brush->id.name) == ID_BR);
|
||||||
|
|
||||||
|
static const Array<std::pair<const char *, int>> mode_map = {
|
||||||
|
{"use_paint_sculpt", OB_MODE_SCULPT},
|
||||||
|
{"use_paint_uv_sculpt", OB_MODE_EDIT},
|
||||||
|
{"use_paint_vertex", OB_MODE_VERTEX_PAINT},
|
||||||
|
{"use_paint_weight", OB_MODE_WEIGHT_PAINT},
|
||||||
|
{"use_paint_image", OB_MODE_TEXTURE_PAINT},
|
||||||
|
{"use_paint_grease_pencil", OB_MODE_PAINT_GPENCIL_LEGACY},
|
||||||
|
{"use_vertex_grease_pencil", OB_MODE_VERTEX_GPENCIL_LEGACY},
|
||||||
|
{"use_paint_sculpt_curves", OB_MODE_SCULPT_CURVES}};
|
||||||
|
|
||||||
|
for (const auto &mode_mapping : mode_map) {
|
||||||
|
/* Only add bools for supported modes. */
|
||||||
|
if (!(brush->ob_mode & mode_mapping.second)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto mode_property = idprop::create_bool(mode_mapping.first, true);
|
||||||
|
BKE_asset_metadata_idprop_ensure(asset_data, mode_property.release());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static AssetTypeInfo AssetType_BR = {
|
||||||
|
/*pre_save_fn*/ brush_asset_metadata_ensure,
|
||||||
|
/*on_mark_asset_fn*/ brush_asset_metadata_ensure,
|
||||||
|
};
|
||||||
|
|
||||||
IDTypeInfo IDType_ID_BR = {
|
IDTypeInfo IDType_ID_BR = {
|
||||||
/*id_code*/ ID_BR,
|
/*id_code*/ ID_BR,
|
||||||
/*id_filter*/ FILTER_ID_BR,
|
/*id_filter*/ FILTER_ID_BR,
|
||||||
|
@ -391,7 +428,7 @@ IDTypeInfo IDType_ID_BR = {
|
||||||
/*name_plural*/ N_("brushes"),
|
/*name_plural*/ N_("brushes"),
|
||||||
/*translation_context*/ BLT_I18NCONTEXT_ID_BRUSH,
|
/*translation_context*/ BLT_I18NCONTEXT_ID_BRUSH,
|
||||||
/*flags*/ IDTYPE_FLAGS_NO_ANIMDATA | IDTYPE_FLAGS_NO_MEMFILE_UNDO,
|
/*flags*/ IDTYPE_FLAGS_NO_ANIMDATA | IDTYPE_FLAGS_NO_MEMFILE_UNDO,
|
||||||
/*asset_type_info*/ nullptr,
|
/*asset_type_info*/ &AssetType_BR,
|
||||||
|
|
||||||
/*init_data*/ brush_init_data,
|
/*init_data*/ brush_init_data,
|
||||||
/*copy_data*/ brush_copy_data,
|
/*copy_data*/ brush_copy_data,
|
||||||
|
|
|
@ -31,6 +31,7 @@ static constexpr StringRef IDP_KEY_SUBTYPE("subtype");
|
||||||
static constexpr StringRef IDP_KEY_VALUE("value");
|
static constexpr StringRef IDP_KEY_VALUE("value");
|
||||||
|
|
||||||
static constexpr StringRef IDP_PROPERTY_TYPENAME_STRING("IDP_STRING");
|
static constexpr StringRef IDP_PROPERTY_TYPENAME_STRING("IDP_STRING");
|
||||||
|
static constexpr StringRef IDP_PROPERTY_TYPENAME_BOOL("IDP_BOOL");
|
||||||
static constexpr StringRef IDP_PROPERTY_TYPENAME_INT("IDP_INT");
|
static constexpr StringRef IDP_PROPERTY_TYPENAME_INT("IDP_INT");
|
||||||
static constexpr StringRef IDP_PROPERTY_TYPENAME_FLOAT("IDP_FLOAT");
|
static constexpr StringRef IDP_PROPERTY_TYPENAME_FLOAT("IDP_FLOAT");
|
||||||
static constexpr StringRef IDP_PROPERTY_TYPENAME_DOUBLE("IDP_DOUBLE");
|
static constexpr StringRef IDP_PROPERTY_TYPENAME_DOUBLE("IDP_DOUBLE");
|
||||||
|
@ -125,6 +126,11 @@ struct DictionaryEntryParser {
|
||||||
return get_string(IDP_KEY_VALUE);
|
return get_string(IDP_KEY_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<bool> get_bool_value() const
|
||||||
|
{
|
||||||
|
return get_bool(IDP_KEY_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<int32_t> get_int_value() const
|
std::optional<int32_t> get_int_value() const
|
||||||
{
|
{
|
||||||
return get_int(IDP_KEY_VALUE);
|
return get_int(IDP_KEY_VALUE);
|
||||||
|
@ -196,6 +202,21 @@ struct DictionaryEntryParser {
|
||||||
return value->as_array_value();
|
return value->as_array_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<bool> get_bool(StringRef key) const
|
||||||
|
{
|
||||||
|
const DictionaryValue::LookupValue *value_ptr = lookup.lookup_ptr(key);
|
||||||
|
if (value_ptr == nullptr) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
const DictionaryValue::LookupValue &value = *value_ptr;
|
||||||
|
|
||||||
|
if (value->type() != eValueType::Boolean) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value->as_boolean_value()->value();
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<int32_t> get_int(StringRef key) const
|
std::optional<int32_t> get_int(StringRef key) const
|
||||||
{
|
{
|
||||||
const DictionaryValue::LookupValue *value_ptr = lookup.lookup_ptr(key);
|
const DictionaryValue::LookupValue *value_ptr = lookup.lookup_ptr(key);
|
||||||
|
@ -321,6 +342,46 @@ class IDPStringSerializer : public IDPropertySerializer {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \brief IDPSerializer for IDP_INT. */
|
||||||
|
class IDPBoolSerializer : public IDPropertySerializer {
|
||||||
|
public:
|
||||||
|
constexpr IDPBoolSerializer() = default;
|
||||||
|
|
||||||
|
std::string type_name() const override
|
||||||
|
{
|
||||||
|
return IDP_PROPERTY_TYPENAME_BOOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<eIDPropertyType> property_type() const override
|
||||||
|
{
|
||||||
|
return IDP_BOOLEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<DictionaryValue> idprop_to_dictionary(
|
||||||
|
const IDProperty *id_property) const override
|
||||||
|
{
|
||||||
|
std::shared_ptr<DictionaryValue> result = create_dictionary(id_property);
|
||||||
|
DictionaryValue::Items &attributes = result->elements();
|
||||||
|
attributes.append_as(std::pair(IDP_KEY_VALUE, new BooleanValue(IDP_Bool(id_property) != 0)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<IDProperty, IDPropertyDeleter> entry_to_idprop(
|
||||||
|
DictionaryEntryParser &entry_reader) const override
|
||||||
|
{
|
||||||
|
BLI_assert(*(entry_reader.get_type()) == IDP_BOOLEAN);
|
||||||
|
std::optional<std::string> name = entry_reader.get_name();
|
||||||
|
if (!name.has_value()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::optional<bool> extracted_value = entry_reader.get_bool_value();
|
||||||
|
if (!extracted_value.has_value()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return create_bool(name->c_str(), *extracted_value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** \brief IDPSerializer for IDP_INT. */
|
/** \brief IDPSerializer for IDP_INT. */
|
||||||
class IDPIntSerializer : public IDPropertySerializer {
|
class IDPIntSerializer : public IDPropertySerializer {
|
||||||
public:
|
public:
|
||||||
|
@ -704,6 +765,7 @@ class IDPUnknownSerializer : public IDPropertySerializer {
|
||||||
|
|
||||||
/* Serializers are constructed statically to remove construction/destruction. */
|
/* Serializers are constructed statically to remove construction/destruction. */
|
||||||
static constexpr IDPStringSerializer IDP_SERIALIZER_STRING;
|
static constexpr IDPStringSerializer IDP_SERIALIZER_STRING;
|
||||||
|
static constexpr IDPIntSerializer IDP_SERIALIZER_BOOL;
|
||||||
static constexpr IDPIntSerializer IDP_SERIALIZER_INT;
|
static constexpr IDPIntSerializer IDP_SERIALIZER_INT;
|
||||||
static constexpr IDPFloatSerializer IDP_SERIALIZER_FLOAT;
|
static constexpr IDPFloatSerializer IDP_SERIALIZER_FLOAT;
|
||||||
static constexpr IDPDoubleSerializer IDP_SERIALIZER_DOUBLE;
|
static constexpr IDPDoubleSerializer IDP_SERIALIZER_DOUBLE;
|
||||||
|
@ -718,6 +780,9 @@ static const IDPropertySerializer &serializer_for(eIDPropertyType property_type)
|
||||||
case IDP_STRING:
|
case IDP_STRING:
|
||||||
return IDP_SERIALIZER_STRING;
|
return IDP_SERIALIZER_STRING;
|
||||||
|
|
||||||
|
case IDP_BOOLEAN:
|
||||||
|
return IDP_SERIALIZER_BOOL;
|
||||||
|
|
||||||
case IDP_INT:
|
case IDP_INT:
|
||||||
return IDP_SERIALIZER_INT;
|
return IDP_SERIALIZER_INT;
|
||||||
|
|
||||||
|
@ -745,6 +810,9 @@ static const IDPropertySerializer &serializer_for(StringRef idprop_typename)
|
||||||
if (idprop_typename == IDP_PROPERTY_TYPENAME_STRING) {
|
if (idprop_typename == IDP_PROPERTY_TYPENAME_STRING) {
|
||||||
return IDP_SERIALIZER_STRING;
|
return IDP_SERIALIZER_STRING;
|
||||||
}
|
}
|
||||||
|
if (idprop_typename == IDP_PROPERTY_TYPENAME_BOOL) {
|
||||||
|
return IDP_SERIALIZER_BOOL;
|
||||||
|
}
|
||||||
if (idprop_typename == IDP_PROPERTY_TYPENAME_INT) {
|
if (idprop_typename == IDP_PROPERTY_TYPENAME_INT) {
|
||||||
return IDP_SERIALIZER_INT;
|
return IDP_SERIALIZER_INT;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue