UI: Asset Shelf (Experimental Feature) #104831

Closed
Julian Eisel wants to merge 399 commits from asset-shelf into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
174 changed files with 1767 additions and 2768 deletions
Showing only changes of commit 0474dcef8e - Show all commits

View File

@ -215,6 +215,7 @@ class GHOST_DeviceVK {
device_features.geometryShader = VK_TRUE;
device_features.dualSrcBlend = VK_TRUE;
device_features.logicOp = VK_TRUE;
device_features.imageCubeArray = VK_TRUE;
#endif
VkDeviceCreateInfo device_create_info = {};
@ -309,7 +310,7 @@ static GHOST_TSuccess ensure_vulkan_device(VkInstance vk_instance,
#if STRICT_REQUIREMENTS
if (!device_vk.features.geometryShader || !device_vk.features.dualSrcBlend ||
!device_vk.features.logicOp)
!device_vk.features.logicOp || !device_vk.features.imageCubeArray)
{
continue;
}

View File

@ -571,8 +571,6 @@ class KeyframesCo:
keyframe_points.foreach_set("co", co_buffer)
keyframe_points.foreach_set("interpolation", ipo_buffer)
# TODO: in Blender 4.0 the next lines can be replaced with one call to `fcurve.update()`.
# See https://projects.blender.org/blender/blender/issues/107126 for more info.
keyframe_points.sort()
keyframe_points.deduplicate()
keyframe_points.handles_recalc()
# This also deduplicates keys where baked keys were inserted on the
# same frame as existing ones.
fcurve.update()

View File

@ -44,8 +44,8 @@ def geometry_modifier_poll(context):
def get_context_modifier(context):
area = context.area
if (area is not None) and (area.type == 'PROPERTIES'):
# Context only has a 'modifier' attribute in the modifier extra operators dropdown.
if hasattr(context, 'modifier'):
modifier = context.modifier
else:
ob = context.object

View File

@ -109,15 +109,7 @@ class MESH_UL_vgroups(UIList):
layout.label(text="", icon_value=icon)
class MESH_UL_fmaps(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.FaceMap))
fmap = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(fmap, "name", text="", emboss=False, icon='FACE_MAPS')
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
class MESH_UL_shape_keys(UIList):
@ -285,50 +277,6 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
layout.prop(context.tool_settings, "vertex_group_weight", text="Weight")
class DATA_PT_face_maps(MeshButtonsPanel, Panel):
bl_label = "Face Maps"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'}
@classmethod
def poll(cls, context):
obj = context.object
return (obj and obj.type == 'MESH')
def draw(self, context):
layout = self.layout
ob = context.object
facemap = ob.face_maps.active
rows = 2
if facemap:
rows = 4
row = layout.row()
row.template_list("MESH_UL_fmaps", "", ob, "face_maps", ob.face_maps, "active_index", rows=rows)
col = row.column(align=True)
col.operator("object.face_map_add", icon='ADD', text="")
col.operator("object.face_map_remove", icon='REMOVE', text="")
if facemap:
col.separator()
col.operator("object.face_map_move", icon='TRIA_UP', text="").direction = 'UP'
col.operator("object.face_map_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
if ob.face_maps and (ob.mode == 'EDIT' and ob.type == 'MESH'):
row = layout.row()
sub = row.row(align=True)
sub.operator("object.face_map_assign", text="Assign")
sub.operator("object.face_map_remove_from", text="Remove")
sub = row.row(align=True)
sub.operator("object.face_map_select", text="Select")
sub.operator("object.face_map_deselect", text="Deselect")
class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
bl_label = "Shape Keys"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'}
@ -717,7 +665,6 @@ classes = (
MESH_MT_color_attribute_context_menu,
MESH_MT_attribute_context_menu,
MESH_UL_vgroups,
MESH_UL_fmaps,
MESH_UL_shape_keys,
MESH_UL_uvmaps,
MESH_UL_attributes,
@ -726,7 +673,6 @@ classes = (
DATA_PT_shape_keys,
DATA_PT_uv_texture,
DATA_PT_vertex_colors,
DATA_PT_face_maps,
DATA_PT_mesh_attributes,
DATA_PT_normals,
DATA_PT_texture_space,

View File

@ -1221,7 +1221,7 @@ class IMAGE_PT_tools_brush_display(Panel, BrushButtonsPanel, DisplayPanel):
bl_context = ".paint_common_2d"
bl_parent_id = "IMAGE_PT_paint_settings"
bl_category = "Tool"
bl_label = "Brush Tip"
bl_label = "Cursor"
bl_options = {'DEFAULT_CLOSED'}
bl_ui_units_x = 15

View File

@ -2106,7 +2106,7 @@ class VIEW3D_MT_select_edit_curves(Menu):
layout.separator()
layout.operator("curves.select_random", text="Random")
layout.operator("curves.select_end", text="Endpoints")
layout.operator("curves.select_ends", text="Endpoints")
layout.operator("curves.select_linked", text="Linked")
layout.separator()
@ -2124,7 +2124,7 @@ class VIEW3D_MT_select_sculpt_curves(Menu):
layout.operator("curves.select_all", text="None").action = 'DESELECT'
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
layout.operator("sculpt_curves.select_random", text="Random")
layout.operator("curves.select_end", text="Endpoints")
layout.operator("curves.select_ends", text="Endpoints")
layout.operator("sculpt_curves.select_grow", text="Grow")

View File

@ -124,6 +124,7 @@ class AssetLibrary {
*/
AssetRepresentation &add_external_asset(StringRef relative_asset_path,
StringRef name,
int id_type,
std::unique_ptr<AssetMetaData> metadata);
/** See #AssetLibrary::add_external_asset(). */
AssetRepresentation &add_local_id_asset(StringRef relative_asset_path, ID &id);

View File

@ -10,6 +10,8 @@
#include "BLI_compiler_attrs.h"
#include "DNA_ID_enums.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -22,6 +24,8 @@ typedef struct AssetRepresentation AssetRepresentation;
const char *AS_asset_representation_name_get(const AssetRepresentation *asset)
ATTR_WARN_UNUSED_RESULT;
ID_Type AS_asset_representation_id_type_get(const AssetRepresentation *asset)
ATTR_WARN_UNUSED_RESULT;
AssetMetaData *AS_asset_representation_metadata_get(const AssetRepresentation *asset)
ATTR_WARN_UNUSED_RESULT;
struct ID *AS_asset_representation_local_id_get(const AssetRepresentation *asset)
@ -30,6 +34,9 @@ bool AS_asset_representation_is_local_id(const AssetRepresentation *asset) ATTR_
bool AS_asset_representation_is_never_link(const AssetRepresentation *asset)
ATTR_WARN_UNUSED_RESULT;
bool AS_asset_representation_may_override_import_method(const AssetRepresentation *asset);
bool AS_asset_representation_use_relative_path_get(const AssetRepresentation *asset);
/**
* C version of #AssetRepresentation::make_weak_reference. Returned pointer needs freeing with
* #MEM_delete() or #BKE_asset_weak_reference_free().

View File

@ -19,6 +19,7 @@
#include "BLI_string_ref.hh"
#include "DNA_ID_enums.h"
#include "DNA_asset_types.h"
#include "AS_asset_identifier.hh"
@ -42,6 +43,7 @@ class AssetRepresentation {
struct ExternalAsset {
std::string name;
int id_type = 0;
std::unique_ptr<AssetMetaData> metadata_ = nullptr;
};
union {
@ -55,6 +57,7 @@ class AssetRepresentation {
/** Constructs an asset representation for an external ID. The asset will not be editable. */
AssetRepresentation(AssetIdentifier &&identifier,
StringRef name,
int id_type,
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library);
/**
@ -85,6 +88,7 @@ class AssetRepresentation {
std::unique_ptr<AssetWeakReference> make_weak_reference() const;
StringRefNull get_name() const;
ID_Type get_id_type() const;
AssetMetaData &get_metadata() const;
/**
* Get the import method to use for this asset. A different one may be used if
@ -116,6 +120,7 @@ struct AssetRepresentation;
const blender::StringRefNull AS_asset_representation_library_relative_identifier_get(
const AssetRepresentation *asset_handle);
std::string AS_asset_representation_full_path_get(const ::AssetRepresentation *asset);
/**
* Get the absolute path to the .blend file containing the given asset. String will be empty if
@ -125,5 +130,3 @@ std::string AS_asset_representation_full_path_get(const ::AssetRepresentation *a
std::string AS_asset_representation_full_library_path_get(const ::AssetRepresentation *asset);
std::optional<eAssetImportMethod> AS_asset_representation_import_method_get(
const ::AssetRepresentation *asset_handle);
bool AS_asset_representation_may_override_import_method(const ::AssetRepresentation *asset_handle);
bool AS_asset_representation_use_relative_path_get(const ::AssetRepresentation *asset_handle);

View File

@ -230,11 +230,12 @@ void AssetLibrary::refresh()
AssetRepresentation &AssetLibrary::add_external_asset(StringRef relative_asset_path,
StringRef name,
const int id_type,
std::unique_ptr<AssetMetaData> metadata)
{
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
return asset_storage_->add_external_asset(
std::move(identifier), name, std::move(metadata), *this);
std::move(identifier), name, id_type, std::move(metadata), *this);
}
AssetRepresentation &AssetLibrary::add_local_id_asset(StringRef relative_asset_path, ID &id)

View File

@ -21,6 +21,7 @@ namespace blender::asset_system {
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
StringRef name,
const int id_type,
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library)
: identifier_(identifier),
@ -29,6 +30,7 @@ AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
external_asset_()
{
external_asset_.name = name;
external_asset_.id_type = id_type;
external_asset_.metadata_ = std::move(metadata);
}
@ -87,6 +89,15 @@ StringRefNull AssetRepresentation::get_name() const
return external_asset_.name;
}
ID_Type AssetRepresentation::get_id_type() const
{
if (is_local_id_) {
return GS(local_asset_id_->name);
}
return ID_Type(external_asset_.id_type);
}
AssetMetaData &AssetRepresentation::get_metadata() const
{
return is_local_id_ ? *local_asset_id_->asset_data : *external_asset_.metadata_;
@ -192,6 +203,13 @@ const char *AS_asset_representation_name_get(const AssetRepresentation *asset_ha
return asset->get_name().c_str();
}
ID_Type AS_asset_representation_id_type_get(const AssetRepresentation *asset_handle)
{
const asset_system::AssetRepresentation *asset =
reinterpret_cast<const asset_system::AssetRepresentation *>(asset_handle);
return asset->get_id_type();
}
AssetMetaData *AS_asset_representation_metadata_get(const AssetRepresentation *asset_handle)
{
const asset_system::AssetRepresentation *asset =

View File

@ -27,11 +27,12 @@ AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifi
AssetRepresentation &AssetStorage::add_external_asset(AssetIdentifier &&identifier,
StringRef name,
const int id_type,
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library)
{
return *external_assets_.lookup_key_or_add(std::make_unique<AssetRepresentation>(
std::move(identifier), name, std::move(metadata), owner_asset_library));
std::move(identifier), name, id_type, std::move(metadata), owner_asset_library));
}
bool AssetStorage::remove_asset(AssetRepresentation &asset)

View File

@ -37,6 +37,7 @@ class AssetStorage {
/** See #AssetLibrary::add_external_asset(). */
AssetRepresentation &add_external_asset(AssetIdentifier &&identifier,
StringRef name,
int id_type,
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library);
/** See #AssetLibrary::add_external_asset(). */

View File

@ -32,7 +32,8 @@ class AssetRepresentationTest : public AssetLibraryTestBase {
AssetRepresentation &add_dummy_asset(AssetLibrary &library, StringRef relative_path)
{
std::unique_ptr<AssetMetaData> dummy_metadata = std::make_unique<AssetMetaData>();
return library.add_external_asset(relative_path, "Some asset name", std::move(dummy_metadata));
return library.add_external_asset(
relative_path, "Some asset name", 0, std::move(dummy_metadata));
}
};

View File

@ -27,13 +27,13 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 5
#define BLENDER_FILE_SUBVERSION 6
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
* was written with too new a version. */
#define BLENDER_FILE_MIN_VERSION 400
#define BLENDER_FILE_MIN_SUBVERSION 2
#define BLENDER_FILE_MIN_SUBVERSION 3
/** User readable version string. */
const char *BKE_blender_version_string(void);

View File

@ -180,8 +180,6 @@ struct Mesh *BKE_mesh_new_nomain_from_curve_displist(const struct Object *ob,
bool BKE_mesh_attribute_required(const char *name);
bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me);
bool BKE_mesh_clear_facemap_customdata(struct Mesh *me);
float (*BKE_mesh_orco_verts_get(struct Object *ob))[3];
void BKE_mesh_orco_verts_transform(struct Mesh *me, float (*orco)[3], int totvert, int invert);

View File

@ -84,6 +84,8 @@ void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh);
void BKE_mesh_legacy_convert_loops_to_corners(struct Mesh *mesh);
void BKE_mesh_legacy_face_map_to_generic(struct Mesh *mesh);
#endif
#ifdef __cplusplus

View File

@ -1,37 +0,0 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup bke
* \brief Functions for dealing with object face-maps.
*/
#ifdef __cplusplus
extern "C" {
#endif
struct ListBase;
struct Object;
struct bFaceMap;
struct bFaceMap *BKE_object_facemap_add(struct Object *ob);
struct bFaceMap *BKE_object_facemap_add_name(struct Object *ob, const char *name);
void BKE_object_facemap_remove(struct Object *ob, struct bFaceMap *fmap);
void BKE_object_facemap_clear(struct Object *ob);
int BKE_object_facemap_name_index(struct Object *ob, const char *name);
void BKE_object_facemap_unique_name(struct Object *ob, struct bFaceMap *fmap);
struct bFaceMap *BKE_object_facemap_find_name(struct Object *ob, const char *name);
void BKE_object_facemap_copy_list(struct ListBase *outbase, const struct ListBase *inbase);
int *BKE_object_facemap_index_map_create(struct Object *ob_src,
struct Object *ob_dst,
int *r_map_len);
void BKE_object_facemap_index_map_apply(int *fmap, int fmap_len, const int *map, int map_len);
#ifdef __cplusplus
}
#endif

View File

@ -241,7 +241,6 @@ set(SRC
intern/object.cc
intern/object_deform.c
intern/object_dupli.cc
intern/object_facemap.c
intern/object_update.cc
intern/ocean.c
intern/ocean_spectrum.c
@ -457,7 +456,6 @@ set(SRC
BKE_node_tree_zones.hh
BKE_object.h
BKE_object_deform.h
BKE_object_facemap.h
BKE_ocean.h
BKE_outliner_treehash.hh
BKE_packedFile.h

View File

@ -1257,20 +1257,6 @@ static void layerSwap_flnor(void *data, const int *corner_indices)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Callbacks for (`int`, #CD_FACEMAP)
* \{ */
static void layerDefault_fmap(void *data, const int count)
{
int *fmap_num = (int *)data;
for (int i = 0; i < count; i++) {
fmap_num[i] = -1;
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Callbacks for (#MPropCol, #CD_PROP_COLOR)
* \{ */
@ -1628,8 +1614,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
nullptr,
nullptr,
layerCopyValue_normal},
/* 9: CD_FACEMAP */
{sizeof(int), "", 0, nullptr, nullptr, nullptr, nullptr, nullptr, layerDefault_fmap, nullptr},
/* 9: CD_FACEMAP */ /* DEPRECATED */
{sizeof(int), ""},
/* 10: CD_PROP_FLOAT */
{sizeof(MFloatProperty),
"MFloatProperty",
@ -1865,7 +1851,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 41: CD_CUSTOMLOOPNORMAL */
{sizeof(short[2]), "vec2s", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 42: CD_SCULPT_FACE_SETS */ /* DEPRECATED */
{sizeof(int), "", 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
{sizeof(int), ""},
/* 43: CD_LOCATION */
{sizeof(float[3]), "vec3f", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 44: CD_RADIUS */
@ -2010,14 +1996,14 @@ const CustomData_MeshMasks CD_MASK_BAREMESH = {
/*vmask*/ CD_MASK_PROP_FLOAT3,
/*emask*/ CD_MASK_PROP_INT32_2D,
/*fmask*/ 0,
/*pmask*/ CD_MASK_FACEMAP,
/*pmask*/ 0,
/*lmask*/ CD_MASK_PROP_INT32,
};
const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = {
/*vmask*/ CD_MASK_PROP_FLOAT3 | CD_MASK_ORIGINDEX,
/*emask*/ CD_MASK_PROP_INT32_2D | CD_MASK_ORIGINDEX,
/*fmask*/ 0,
/*pmask*/ CD_MASK_FACEMAP | CD_MASK_ORIGINDEX,
/*pmask*/ CD_MASK_ORIGINDEX,
/*lmask*/ CD_MASK_PROP_INT32,
};
const CustomData_MeshMasks CD_MASK_MESH = {
@ -2027,7 +2013,7 @@ const CustomData_MeshMasks CD_MASK_MESH = {
(CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_CREASE),
/*fmask*/ 0,
/*pmask*/
(CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
(CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/*lmask*/
(CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
};
@ -2039,7 +2025,7 @@ const CustomData_MeshMasks CD_MASK_DERIVEDMESH = {
(CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_CREASE),
/*fmask*/ (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT),
/*pmask*/
(CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL),
(CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/*lmask*/
(CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP |
CD_MASK_PROP_ALL), /* XXX: MISSING #CD_MASK_MLOOPTANGENT ? */
@ -2050,7 +2036,7 @@ const CustomData_MeshMasks CD_MASK_BMESH = {
/*emask*/ (CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL),
/*fmask*/ 0,
/*pmask*/
(CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL),
(CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/*lmask*/
(CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
};
@ -2066,8 +2052,7 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = {
CD_MASK_ORIGSPACE | CD_MASK_TANGENT | CD_MASK_TESSLOOPNORMAL | CD_MASK_PREVIEW_MCOL |
CD_MASK_PROP_ALL),
/*pmask*/
(CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE |
CD_MASK_PROP_ALL),
(CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/*lmask*/
(CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL |
CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP |
@ -5169,9 +5154,6 @@ void CustomData_blend_write(BlendWriter *writer,
case CD_GRID_PAINT_MASK:
write_grid_paint_mask(writer, count, static_cast<const GridPaintMask *>(layer.data));
break;
case CD_FACEMAP:
BLO_write_raw(writer, sizeof(int) * count, static_cast<const int *>(layer.data));
break;
case CD_PROP_BOOL:
BLO_write_raw(writer, sizeof(bool) * count, static_cast<const bool *>(layer.data));
break;

View File

@ -808,44 +808,6 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me)
}
}
bool BKE_mesh_ensure_facemap_customdata(Mesh *me)
{
BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr;
bool changed = false;
if (bm) {
if (!CustomData_has_layer(&bm->pdata, CD_FACEMAP)) {
BM_data_layer_add(bm, &bm->pdata, CD_FACEMAP);
changed = true;
}
}
else {
if (!CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
CustomData_add_layer(&me->pdata, CD_FACEMAP, CD_SET_DEFAULT, me->totpoly);
changed = true;
}
}
return changed;
}
bool BKE_mesh_clear_facemap_customdata(Mesh *me)
{
BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr;
bool changed = false;
if (bm) {
if (CustomData_has_layer(&bm->pdata, CD_FACEMAP)) {
BM_data_layer_free(bm, &bm->pdata, CD_FACEMAP);
changed = true;
}
}
else {
if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
CustomData_free_layers(&me->pdata, CD_FACEMAP, me->totpoly);
changed = true;
}
}
return changed;
}
bool BKE_mesh_has_custom_loop_normals(Mesh *me)
{
if (me->edit_mesh) {

View File

@ -1305,6 +1305,40 @@ void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Face Map Conversion
* \{ */
void BKE_mesh_legacy_face_map_to_generic(Mesh *mesh)
{
using namespace blender;
if (mesh->attributes().contains("face_maps")) {
return;
}
void *data = nullptr;
const ImplicitSharingInfo *sharing_info = nullptr;
for (const int i : IndexRange(mesh->pdata.totlayer)) {
CustomDataLayer &layer = mesh->pdata.layers[i];
if (layer.type == CD_FACEMAP) {
data = layer.data;
sharing_info = layer.sharing_info;
layer.data = nullptr;
layer.sharing_info = nullptr;
CustomData_free_layer(&mesh->pdata, CD_FACEMAP, mesh->totpoly, i);
break;
}
}
if (data != nullptr) {
CustomData_add_layer_named_with_data(
&mesh->pdata, CD_PROP_INT32, data, mesh->totpoly, "face_maps", sharing_info);
}
if (sharing_info != nullptr) {
sharing_info->remove_user_and_delete_if_last();
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Bevel Weight Conversion
* \{ */

View File

@ -16,9 +16,9 @@
#include "MEM_guardedalloc.h"
#include "BLI_array.hh"
#include "BLI_array_utils.hh"
#include "BLI_index_range.hh"
#include "BLI_math_vector.h"
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
#include "BLI_task.hh"
@ -27,6 +27,7 @@
#include "BKE_attribute.h"
#include "BKE_attribute.hh"
#include "BKE_attribute_math.hh"
#include "BKE_bvhutils.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
@ -35,6 +36,7 @@
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remesh_voxel.h" /* own include */
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_sample.hh"
#include "bmesh_tools.h"
@ -360,116 +362,104 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
{
BVHTreeFromMesh bvhtree = {nullptr};
BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2);
using namespace blender;
using namespace blender::bke;
const AttributeAccessor src_attributes = source->attributes();
MutableAttributeAccessor dst_attributes = target->attributes_for_write();
int i = 0;
const CustomDataLayer *layer;
Vector<AttributeIDRef> point_ids;
Vector<AttributeIDRef> corner_ids;
source->attributes().for_all([&](const AttributeIDRef &id, const AttributeMetaData &meta_data) {
if (CD_TYPE_AS_MASK(meta_data.data_type) & CD_MASK_COLOR_ALL) {
if (meta_data.domain == ATTR_DOMAIN_POINT) {
point_ids.append(id);
}
else if (meta_data.domain == ATTR_DOMAIN_CORNER) {
corner_ids.append(id);
}
}
return true;
});
if (point_ids.is_empty() && corner_ids.is_empty()) {
return;
}
Array<int> source_vert_to_loop_offsets;
Array<int> source_vert_to_loop_indices;
blender::GroupedSpan<int> source_lmap;
GroupedSpan<int> source_lmap;
Array<int> target_vert_to_loop_offsets;
Array<int> target_vert_to_loop_indices;
blender::GroupedSpan<int> target_lmap;
GroupedSpan<int> target_lmap;
BVHTreeFromMesh bvhtree = {nullptr};
threading::parallel_invoke(
[&]() { BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2); },
[&]() {
source_lmap = mesh::build_vert_to_loop_map(source->corner_verts(),
source->totvert,
source_vert_to_loop_offsets,
source_vert_to_loop_indices);
},
[&]() {
target_lmap = mesh::build_vert_to_loop_map(target->corner_verts(),
target->totvert,
target_vert_to_loop_offsets,
target_vert_to_loop_indices);
});
while ((layer = BKE_id_attribute_from_index(
const_cast<ID *>(&source->id), i++, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL)))
{
eAttrDomain domain = BKE_id_attribute_domain(&source->id, layer);
const eCustomDataType type = eCustomDataType(layer->type);
CustomData *target_cdata = domain == ATTR_DOMAIN_POINT ? &target->vdata : &target->ldata;
const CustomData *source_cdata = domain == ATTR_DOMAIN_POINT ? &source->vdata : &source->ldata;
/* Check attribute exists in target. */
int layer_i = CustomData_get_named_layer_index(target_cdata, type, layer->name);
if (layer_i == -1) {
int elem_num = domain == ATTR_DOMAIN_POINT ? target->totvert : target->totloop;
CustomData_add_layer_named(target_cdata, type, CD_SET_DEFAULT, elem_num, layer->name);
layer_i = CustomData_get_named_layer_index(target_cdata, type, layer->name);
const Span<float3> target_positions = target->vert_positions();
Array<int> nearest_src_verts(target_positions.size());
threading::parallel_for(target_positions.index_range(), 1024, [&](const IndexRange range) {
for (const int i : range) {
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
BLI_bvhtree_find_nearest(
bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree);
nearest_src_verts[i] = nearest.index;
}
});
size_t data_size = CustomData_sizeof(type);
void *target_data = target_cdata->layers[layer_i].data;
void *source_data = layer->data;
const Span<float3> target_positions = target->vert_positions();
for (const AttributeIDRef &id : point_ids) {
const GVArraySpan src = *src_attributes.lookup(id, ATTR_DOMAIN_POINT);
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
id, ATTR_DOMAIN_POINT, cpp_type_to_custom_data_type(src.type()));
attribute_math::gather(src, nearest_src_verts, dst.span);
dst.finish();
}
if (domain == ATTR_DOMAIN_POINT) {
blender::threading::parallel_for(
IndexRange(target->totvert), 4096, [&](const IndexRange range) {
for (const int i : range) {
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
BLI_bvhtree_find_nearest(
bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index != -1) {
memcpy(POINTER_OFFSET(target_data, size_t(i) * data_size),
POINTER_OFFSET(source_data, size_t(nearest.index) * data_size),
data_size);
if (!corner_ids.is_empty()) {
for (const AttributeIDRef &id : corner_ids) {
const GVArraySpan src = *src_attributes.lookup(id, ATTR_DOMAIN_CORNER);
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
id, ATTR_DOMAIN_CORNER, cpp_type_to_custom_data_type(src.type()));
threading::parallel_for(target_positions.index_range(), 1024, [&](const IndexRange range) {
src.type().to_static_type_tag<ColorGeometry4b, ColorGeometry4f>([&](auto type_tag) {
using T = typename decltype(type_tag)::type;
if constexpr (std::is_void_v<T>) {
BLI_assert_unreachable();
}
else {
const Span<T> src_typed = src.typed<T>();
MutableSpan<T> dst_typed = dst.span.typed<T>();
for (const int dst_vert : range) {
/* Find the average value at the corners of the closest vertex on the
* source mesh. */
const int src_vert = nearest_src_verts[dst_vert];
T value;
typename blender::bke::attribute_math::DefaultMixer<T> mixer({&value, 1});
for (const int corner : source_lmap[src_vert]) {
mixer.mix_in(0, src_typed[corner]);
}
dst_typed.fill_indices(target_lmap[dst_vert], value);
}
});
}
else {
/* Lazily init vertex -> loop maps. */
if (source_lmap.is_empty()) {
source_lmap = blender::bke::mesh::build_vert_to_loop_map(source->corner_verts(),
source->totvert,
source_vert_to_loop_offsets,
source_vert_to_loop_indices);
target_lmap = blender::bke::mesh::build_vert_to_loop_map(target->corner_verts(),
target->totvert,
target_vert_to_loop_offsets,
target_vert_to_loop_indices);
}
}
});
});
blender::threading::parallel_for(
IndexRange(target->totvert), 2048, [&](const IndexRange range) {
for (const int i : range) {
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
BLI_bvhtree_find_nearest(
bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index == -1) {
continue;
}
const Span<int> source_loops = source_lmap[nearest.index];
const Span<int> target_loops = target_lmap[i];
if (target_loops.size() == 0 || source_loops.size() == 0) {
continue;
}
/*
* Average color data for loops around the source vertex into
* the first target loop around the target vertex
*/
CustomData_interp(source_cdata,
target_cdata,
source_loops.data(),
nullptr,
nullptr,
source_loops.size(),
target_loops[0]);
void *elem = POINTER_OFFSET(target_data, size_t(target_loops[0]) * data_size);
/* Copy to rest of target loops. */
for (int j = 1; j < target_loops.size(); j++) {
memcpy(POINTER_OFFSET(target_data, size_t(target_loops[j]) * data_size),
elem,
data_size);
}
}
});
dst.finish();
}
}

View File

@ -759,6 +759,10 @@ class NodeTreeMainUpdater {
LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
link->flag |= NODE_LINK_VALID;
if (!link->fromsock->is_available() || !link->tosock->is_available()) {
link->flag &= ~NODE_LINK_VALID;
continue;
}
const bNode &from_node = *link->fromnode;
const bNode &to_node = *link->tonode;
if (toposort_indices[from_node.index()] > toposort_indices[to_node.index()]) {

View File

@ -114,7 +114,6 @@
#include "BKE_multires.h"
#include "BKE_node.hh"
#include "BKE_object.h"
#include "BKE_object_facemap.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_pbvh.h"
@ -233,7 +232,6 @@ static void object_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const in
}
}
BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps);
BKE_constraints_copy_ex(&ob_dst->constraints, &ob_src->constraints, flag_subdata, true);
ob_dst->mode = ob_dst->type != OB_GPENCIL_LEGACY ? OB_MODE_OBJECT : ob_dst->mode;
@ -302,7 +300,6 @@ static void object_free_data(ID *id)
MEM_SAFE_FREE(ob->iuser);
MEM_SAFE_FREE(ob->runtime.bb);
BLI_freelistN(&ob->fmaps);
if (ob->pose) {
BKE_pose_free_ex(ob->pose, false);
ob->pose = nullptr;
@ -546,13 +543,6 @@ static void object_foreach_path(ID *id, BPathForeachPathData *bpath_data)
}
}
static void write_fmaps(BlendWriter *writer, ListBase *fbase)
{
LISTBASE_FOREACH (bFaceMap *, fmap, fbase) {
BLO_write_struct(writer, bFaceMap, fmap);
}
}
static void object_blend_write(BlendWriter *writer, ID *id, const void *id_address)
{
Object *ob = (Object *)id;
@ -586,7 +576,6 @@ static void object_blend_write(BlendWriter *writer, ID *id, const void *id_addre
}
BKE_pose_blend_write(writer, ob->pose, arm);
write_fmaps(writer, &ob->fmaps);
BKE_constraint_blend_write(writer, &ob->constraints);
animviz_motionpath_blend_write(writer, ob->mpath);
@ -682,7 +671,6 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
/* Only for versioning, vertex group names are now stored on object data. */
BLO_read_list(reader, &ob->defbase);
BLO_read_list(reader, &ob->fmaps);
/* XXX deprecated - old animation system <<< */
direct_link_nlastrips(reader, &ob->nlastrips);
BLO_read_list(reader, &ob->constraintChannels);

View File

@ -1,286 +0,0 @@
/* SPDX-FileCopyrightText: 2008 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup bke
*/
#include <string.h>
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
#include "BKE_object_facemap.h" /* own include */
#include "BLT_translation.h"
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "RNA_define.h"
static bool fmap_unique_check(void *arg, const char *name)
{
struct {
Object *ob;
void *fm;
} *data = arg;
bFaceMap *fmap;
for (fmap = data->ob->fmaps.first; fmap; fmap = fmap->next) {
if (data->fm != fmap) {
if (STREQ(fmap->name, name)) {
return true;
}
}
}
return false;
}
static bFaceMap *fmap_duplicate(bFaceMap *infmap)
{
bFaceMap *outfmap;
if (!infmap) {
return NULL;
}
outfmap = MEM_callocN(sizeof(bFaceMap), "copy facemap");
/* For now, just copy everything over. */
memcpy(outfmap, infmap, sizeof(bFaceMap));
outfmap->next = outfmap->prev = NULL;
return outfmap;
}
void BKE_object_facemap_copy_list(ListBase *outbase, const ListBase *inbase)
{
bFaceMap *fmap, *fmapn;
BLI_listbase_clear(outbase);
for (fmap = inbase->first; fmap; fmap = fmap->next) {
fmapn = fmap_duplicate(fmap);
BLI_addtail(outbase, fmapn);
}
}
void BKE_object_facemap_unique_name(Object *ob, bFaceMap *fmap)
{
struct {
Object *ob;
void *fmap;
} data;
data.ob = ob;
data.fmap = fmap;
BLI_uniquename_cb(fmap_unique_check, &data, DATA_("Group"), '.', fmap->name, sizeof(fmap->name));
}
bFaceMap *BKE_object_facemap_add_name(Object *ob, const char *name)
{
bFaceMap *fmap;
if (!ob || ob->type != OB_MESH) {
return NULL;
}
fmap = MEM_callocN(sizeof(bFaceMap), __func__);
STRNCPY(fmap->name, name);
BLI_addtail(&ob->fmaps, fmap);
ob->actfmap = BLI_listbase_count(&ob->fmaps);
BKE_object_facemap_unique_name(ob, fmap);
return fmap;
}
bFaceMap *BKE_object_facemap_add(Object *ob)
{
return BKE_object_facemap_add_name(ob, DATA_("FaceMap"));
}
static void object_fmap_remove_edit_mode(Object *ob, bFaceMap *fmap, bool do_selected, bool purge)
{
const int fmap_nr = BLI_findindex(&ob->fmaps, fmap);
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
if (me->edit_mesh) {
BMEditMesh *em = me->edit_mesh;
const int cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
if (cd_fmap_offset != -1) {
BMFace *efa;
BMIter iter;
int *map;
if (purge) {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (map) {
if (*map == fmap_nr) {
*map = -1;
}
else if (*map > fmap_nr) {
*map -= 1;
}
}
}
}
else {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (map && *map == fmap_nr && (!do_selected || BM_elem_flag_test(efa, BM_ELEM_SELECT)))
{
*map = -1;
}
}
}
}
if (ob->actfmap == BLI_listbase_count(&ob->fmaps)) {
ob->actfmap--;
}
BLI_remlink(&ob->fmaps, fmap);
MEM_freeN(fmap);
}
}
}
static void object_fmap_remove_object_mode(Object *ob, bFaceMap *fmap, bool purge)
{
const int fmap_nr = BLI_findindex(&ob->fmaps, fmap);
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
int *map = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly);
int i;
if (map) {
for (i = 0; i < me->totpoly; i++) {
if (map[i] == fmap_nr) {
map[i] = -1;
}
else if (purge && map[i] > fmap_nr) {
map[i]--;
}
}
}
}
if (ob->actfmap == BLI_listbase_count(&ob->fmaps)) {
ob->actfmap--;
}
BLI_remlink(&ob->fmaps, fmap);
MEM_freeN(fmap);
}
}
static void fmap_remove_exec(Object *ob, bFaceMap *fmap, const bool is_edit_mode, const bool purge)
{
if (is_edit_mode) {
object_fmap_remove_edit_mode(ob, fmap, false, purge);
}
else {
object_fmap_remove_object_mode(ob, fmap, purge);
}
}
void BKE_object_facemap_remove(Object *ob, bFaceMap *fmap)
{
fmap_remove_exec(ob, fmap, BKE_object_is_in_editmode(ob), true);
}
void BKE_object_facemap_clear(Object *ob)
{
bFaceMap *fmap = (bFaceMap *)ob->fmaps.first;
if (fmap) {
const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob);
while (fmap) {
bFaceMap *next_fmap = fmap->next;
fmap_remove_exec(ob, fmap, edit_mode, false);
fmap = next_fmap;
}
}
/* remove all face-maps */
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
CustomData_free_layer(&me->pdata, CD_FACEMAP, me->totpoly, 0);
}
ob->actfmap = 0;
}
int BKE_object_facemap_name_index(Object *ob, const char *name)
{
return (name) ? BLI_findstringindex(&ob->fmaps, name, offsetof(bFaceMap, name)) : -1;
}
bFaceMap *BKE_object_facemap_find_name(Object *ob, const char *name)
{
return BLI_findstring(&ob->fmaps, name, offsetof(bFaceMap, name));
}
int *BKE_object_facemap_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len)
{
/* Build src to merged mapping of facemap indices. */
if (BLI_listbase_is_empty(&ob_src->fmaps) || BLI_listbase_is_empty(&ob_dst->fmaps)) {
*r_map_len = 0;
return NULL;
}
*r_map_len = BLI_listbase_count(&ob_src->fmaps);
int *fmap_index_map = MEM_malloc_arrayN(
*r_map_len, sizeof(*fmap_index_map), "defgroup index map create");
bool is_fmap_remap_needed = false;
int i = 0;
for (bFaceMap *fmap_src = ob_src->fmaps.first; fmap_src; fmap_src = fmap_src->next, i++) {
fmap_index_map[i] = BKE_object_facemap_name_index(ob_dst, fmap_src->name);
is_fmap_remap_needed = is_fmap_remap_needed || (fmap_index_map[i] != i);
}
if (!is_fmap_remap_needed) {
MEM_freeN(fmap_index_map);
fmap_index_map = NULL;
*r_map_len = 0;
}
return fmap_index_map;
}
void BKE_object_facemap_index_map_apply(int *fmap, int fmap_len, const int *map, int map_len)
{
if (map == NULL || map_len == 0) {
return;
}
for (int i = 0; i < fmap_len; i++, fmap++) {
*fmap = (*fmap < map_len && *fmap != -1) ? map[*fmap] : -1;
}
}

View File

@ -1569,7 +1569,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
loopindex2);
loopindex2++;
/* Copy over poly data, e.g. #CD_FACEMAP. */
CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1);
if (polyOrigIndex) {

View File

@ -186,7 +186,7 @@ bool BLI_is_file(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
*/
bool BLI_dir_create_recursive(const char *dir) ATTR_NONNULL();
/**
* Returns the number of free bytes on the volume containing the specified pathname.
* Returns the number of free bytes on the volume containing the specified path.
*
* \note Not actually used anywhere.
*/

View File

@ -74,12 +74,6 @@ template<typename T> struct AngleRadianBase {
/** Methods. */
/* 'mod_inline(-3, 4)= 1', 'fmod(-3, 4)= -3' */
static float mod_inline(float a, float b)
{
return a - (b * floorf(a / b));
}
/**
* Return the angle wrapped inside [-pi..pi] interval. Basically `(angle + pi) % 2pi - pi`.
*/

View File

@ -171,6 +171,11 @@ template<typename T> inline T pow(const T &x, const T &power)
return std::pow(x, power);
}
template<typename T> inline T exp(const T &x)
{
return std::exp(x);
}
template<typename T> inline T safe_acos(const T &a)
{
if (UNLIKELY(a <= T(-1))) {

View File

@ -680,7 +680,7 @@ template<typename T> QuaternionBase<T> QuaternionBase<T>::expmap(const VecBase<T
T angle;
const VecBase<T, 3> axis = normalize_and_get_length(expmap, angle);
if (LIKELY(angle != T(0))) {
return to_quaternion(AxisAngleT(axis, angle_wrap_rad(angle)));
return to_quaternion(AxisAngleT(axis, AngleRadianBase<T>(angle).wrapped()));
}
return QuaternionBase<T>::identity();
}

View File

@ -162,6 +162,11 @@ template<typename T> struct QuaternionBase {
return (a.w == b.w) && (a.x == b.x) && (a.y == b.y) && (a.z == b.z);
}
uint64_t hash() const
{
return VecBase<T, 4>(*this).hash();
}
friend std::ostream &operator<<(std::ostream &stream, const QuaternionBase &rot)
{
return stream << "Quaternion" << static_cast<VecBase<T, 4>>(rot);

View File

@ -206,6 +206,16 @@ template<typename T, int Size>
return result;
}
/* Per-element exponent. */
template<typename T, int Size> [[nodiscard]] inline VecBase<T, Size> exp(const VecBase<T, Size> &x)
{
VecBase<T, Size> result;
for (int i = 0; i < Size; i++) {
result[i] = math::exp(x[i]);
}
return result;
}
/**
* Returns \a a if it is a multiple of \a b or the next multiple or \a b after \b a .
* In other words, it is equivalent to `divide_ceil(a, b) * b`.

View File

@ -34,7 +34,7 @@ extern "C" {
#define BLI_STR_FORMAT_INT32_INTEGER_UNIT_SIZE 5
/**
* Duplicates the first \a len bytes of cstring \a str
* Duplicates the first \a len bytes of the C-string \a str
* into a newly mallocN'd string and returns it. \a str
* is assumed to be at least len bytes long.
*
@ -45,7 +45,7 @@ extern "C" {
char *BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
/**
* Duplicates the cstring \a str into a newly mallocN'd
* Duplicates the C-string \a str into a newly mallocN'd
* string and returns it.
*
* \param str: The string to be duplicated

View File

@ -172,4 +172,13 @@ TEST(math_vector, safe_rcp)
EXPECT_NEAR(result.z, 0.25f, 1e-6f);
}
TEST(math_vector, exp)
{
const float3 a(1.0f, 2.0f, 3.0f);
const float3 result = math::exp(a);
EXPECT_NEAR(result.x, 2.718281828459045f, 1e-6f);
EXPECT_NEAR(result.y, 7.38905609893065f, 1e-6f);
EXPECT_NEAR(result.z, 20.085536923187668f, 1e-6f);
}
} // namespace blender::tests

View File

@ -76,7 +76,10 @@ typedef struct BlendFileReadWMSetupData {
/** The existing WM when filereading process is started. */
struct wmWindowManager *old_wm;
/** The startup file is being read. */
bool is_read_homefile;
/** The factory startup file is being read. */
bool is_factory_startup;
} BlendFileReadWMSetupData;
struct BlendFileReadParams {

View File

@ -185,14 +185,30 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 400, 5)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
ToolSettings *ts = scene->toolsettings;
if (ts->snap_mode_tools != SCE_SNAP_MODE_NONE) {
ts->snap_mode_tools = SCE_SNAP_MODE_GEOM;
}
#define SCE_SNAP_PROJECT (1 << 3)
if (scene->toolsettings->snap_flag & SCE_SNAP_PROJECT) {
scene->toolsettings->snap_mode |= SCE_SNAP_MODE_FACE_RAYCAST;
if (ts->snap_flag & SCE_SNAP_PROJECT) {
ts->snap_mode |= SCE_SNAP_MODE_FACE_RAYCAST;
}
#undef SCE_SNAP_PROJECT
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 400, 6)) {
LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
BKE_mesh_legacy_face_map_to_generic(mesh);
}
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
versioning_replace_legacy_glossy_node(ntree);
versioning_remove_microfacet_sharp_distribution(ntree);
}
FOREACH_NODETREE_END;
}
/**
* Versioning code until next subversion bump goes here.
*
@ -207,11 +223,6 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
*/
{
/* Convert anisotropic BSDF node to glossy BSDF. */
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
versioning_replace_legacy_glossy_node(ntree);
versioning_remove_microfacet_sharp_distribution(ntree);
}
FOREACH_NODETREE_END;
/* Keep this block, even when empty. */
}

View File

@ -72,7 +72,7 @@ set(SRC
intern/bmesh_edgeloop.c
intern/bmesh_edgeloop.h
intern/bmesh_inline.h
intern/bmesh_interp.c
intern/bmesh_interp.cc
intern/bmesh_interp.h
intern/bmesh_iterators.cc
intern/bmesh_iterators.h

View File

@ -35,7 +35,7 @@ typedef struct BMEdgeLoopStore {
#define EDGELOOP_EPS 1e-10f
/* -------------------------------------------------------------------- */
/* BM_mesh_edgeloops_find & Util Functions. */
/* BM_mesh_edgeloops_find & Utility Functions. */
static int bm_vert_other_tag(BMVert *v, BMVert *v_prev, BMEdge **r_e)
{

View File

@ -63,7 +63,7 @@ static void bm_data_interp_from_elem(CustomData *data_layer,
src[1] = ele_src_2->head.data;
w[0] = 1.0f - fac;
w[1] = fac;
CustomData_bmesh_interp(data_layer, src, w, NULL, 2, ele_dst->head.data);
CustomData_bmesh_interp(data_layer, src, w, nullptr, 2, ele_dst->head.data);
}
}
}
@ -88,21 +88,21 @@ void BM_data_interp_from_edges(
* Sets all the customdata (e.g. vert, loop) associated with a vert
* to the average of the face regions surrounding it.
*/
static void UNUSED_FUNCTION(BM_Data_Vert_Average)(BMesh *UNUSED(bm), BMFace *UNUSED(f))
static void UNUSED_FUNCTION(BM_Data_Vert_Average)(BMesh * /*bm*/, BMFace * /*f*/)
{
// BMIter iter;
}
void BM_data_interp_face_vert_edge(BMesh *bm,
const BMVert *v_src_1,
const BMVert *UNUSED(v_src_2),
const BMVert * /*v_src_2*/,
BMVert *v,
BMEdge *e,
const float fac)
{
float w[2];
BMLoop *l_v1 = NULL, *l_v = NULL, *l_v2 = NULL;
BMLoop *l_iter = NULL;
BMLoop *l_v1 = nullptr, *l_v = nullptr, *l_v2 = nullptr;
BMLoop *l_iter = nullptr;
if (!e->l) {
return;
@ -132,7 +132,7 @@ void BM_data_interp_face_vert_edge(BMesh *bm,
src[0] = l_v1->head.data;
src[1] = l_v2->head.data;
CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_v->head.data);
CustomData_bmesh_interp(&bm->ldata, src, w, nullptr, 2, l_v->head.data);
} while ((l_iter = l_iter->radial_next) != e->l);
}
@ -148,7 +148,7 @@ void BM_face_interp_from_face_ex(BMesh *bm,
BMLoop *l_iter;
BMLoop *l_first;
float *w = BLI_array_alloca(w, f_src->len);
float *w = static_cast<float *>(BLI_array_alloca(w, f_src->len));
float co[2];
if (f_src != f_dst) {
@ -160,9 +160,9 @@ void BM_face_interp_from_face_ex(BMesh *bm,
do {
mul_v2_m3v3(co, axis_mat, l_iter->v->co);
interp_weights_poly_v2(w, cos_2d, f_src->len, co);
CustomData_bmesh_interp(&bm->ldata, blocks_l, w, NULL, f_src->len, l_iter->head.data);
CustomData_bmesh_interp(&bm->ldata, blocks_l, w, nullptr, f_src->len, l_iter->head.data);
if (do_vertex) {
CustomData_bmesh_interp(&bm->vdata, blocks_v, w, NULL, f_src->len, l_iter->v->head.data);
CustomData_bmesh_interp(&bm->vdata, blocks_v, w, nullptr, f_src->len, l_iter->v->head.data);
}
} while ((l_iter = l_iter->next) != l_first);
}
@ -172,9 +172,11 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, con
BMLoop *l_iter;
BMLoop *l_first;
const void **blocks_l = BLI_array_alloca(blocks_l, f_src->len);
const void **blocks_v = do_vertex ? BLI_array_alloca(blocks_v, f_src->len) : NULL;
float(*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
const void **blocks_l = static_cast<const void **>(BLI_array_alloca(blocks_l, f_src->len));
const void **blocks_v = do_vertex ?
static_cast<const void **>(BLI_array_alloca(blocks_v, f_src->len)) :
nullptr;
float(*cos_2d)[2] = static_cast<float(*)[2]>(BLI_array_alloca(cos_2d, f_src->len));
float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
int i;
@ -287,7 +289,7 @@ static bool quad_co(const float v1[3],
static void mdisp_axis_from_quad(const float v1[3],
const float v2[3],
float UNUSED(v3[3]),
float[3] /*v3[3]*/,
const float v4[3],
float r_axis_x[3],
float r_axis_y[3])
@ -421,9 +423,9 @@ typedef struct BMLoopInterpMultiresData {
static void loop_interp_multires_cb(void *__restrict userdata,
const int ix,
const TaskParallelTLS *__restrict UNUSED(tls))
const TaskParallelTLS *__restrict /*tls*/)
{
BMLoopInterpMultiresData *data = userdata;
BMLoopInterpMultiresData *data = static_cast<BMLoopInterpMultiresData *>(userdata);
BMLoop *l_first = data->l_src_first;
BMLoop *l_dst = data->l_dst;
@ -458,7 +460,7 @@ static void loop_interp_multires_cb(void *__restrict userdata,
float src_axis_x[3], src_axis_y[3];
float uv[2];
md_src = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset);
md_src = static_cast<MDisps *>(BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset));
if (mdisp_in_mdispquad(l_dst, l_iter, f_src_center, co, res, src_axis_x, src_axis_y, uv)) {
old_mdisps_bilinear(md_dst->disps[iy * res + ix], md_src->disps, res, uv[0], uv[1]);
@ -470,7 +472,7 @@ static void loop_interp_multires_cb(void *__restrict userdata,
}
}
void BM_loop_interp_multires_ex(BMesh *UNUSED(bm),
void BM_loop_interp_multires_ex(BMesh * /*bm*/,
BMLoop *l_dst,
const BMFace *f_src,
const float f_dst_center[3],
@ -486,17 +488,19 @@ void BM_loop_interp_multires_ex(BMesh *UNUSED(bm),
return;
}
md_dst = BM_ELEM_CD_GET_VOID_P(l_dst, cd_loop_mdisp_offset);
md_dst = static_cast<MDisps *>(BM_ELEM_CD_GET_VOID_P(l_dst, cd_loop_mdisp_offset));
compute_mdisp_quad(l_dst, f_dst_center, v1, v2, v3, v4, e1, e2);
/* if no disps data allocate a new grid, the size of the first grid in f_src. */
if (!md_dst->totdisp) {
const MDisps *md_src = BM_ELEM_CD_GET_VOID_P(BM_FACE_FIRST_LOOP(f_src), cd_loop_mdisp_offset);
const MDisps *md_src = static_cast<const MDisps *>(
BM_ELEM_CD_GET_VOID_P(BM_FACE_FIRST_LOOP(f_src), cd_loop_mdisp_offset));
md_dst->totdisp = md_src->totdisp;
md_dst->level = md_src->level;
if (md_dst->totdisp) {
md_dst->disps = MEM_callocN(sizeof(float[3]) * md_dst->totdisp, __func__);
md_dst->disps = static_cast<float(*)[3]>(
MEM_callocN(sizeof(float[3]) * md_dst->totdisp, __func__));
}
else {
return;
@ -506,21 +510,21 @@ void BM_loop_interp_multires_ex(BMesh *UNUSED(bm),
mdisp_axis_from_quad(v1, v2, v3, v4, axis_x, axis_y);
const int res = (int)sqrt(md_dst->totdisp);
BMLoopInterpMultiresData data = {
.l_dst = l_dst,
.l_src_first = BM_FACE_FIRST_LOOP(f_src),
.cd_loop_mdisp_offset = cd_loop_mdisp_offset,
.md_dst = md_dst,
.f_src_center = f_src_center,
.axis_x = axis_x,
.axis_y = axis_y,
.v1 = v1,
.v4 = v4,
.e1 = e1,
.e2 = e2,
.res = res,
.d = 1.0f / (float)(res - 1),
};
BMLoopInterpMultiresData data = {};
data.l_dst = l_dst;
data.l_src_first = BM_FACE_FIRST_LOOP(f_src);
data.cd_loop_mdisp_offset = cd_loop_mdisp_offset;
data.md_dst = md_dst;
data.f_src_center = f_src_center;
data.axis_x = axis_x;
data.axis_y = axis_y;
data.v1 = v1;
data.v4 = v4;
data.e1 = e1;
data.e2 = e2;
data.res = res;
data.d = 1.0f / (float)(res - 1);
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.use_threading = (res > 5);
@ -583,9 +587,9 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
}
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *mdp = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_mdisp_offset);
MDisps *mdl = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
MDisps *mdn = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_mdisp_offset);
MDisps *mdp = static_cast<MDisps *>(BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_mdisp_offset));
MDisps *mdl = static_cast<MDisps *>(BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset));
MDisps *mdn = static_cast<MDisps *>(BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_mdisp_offset));
float co1[3];
int sides;
int y;
@ -615,7 +619,7 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
}
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *mdl1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
MDisps *mdl1 = static_cast<MDisps *>(BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset));
MDisps *mdl2;
float co1[3], co2[3], co[3];
int sides;
@ -641,10 +645,11 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
}
if (l->radial_next->v == l->v) {
mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next, cd_loop_mdisp_offset);
mdl2 = static_cast<MDisps *>(BM_ELEM_CD_GET_VOID_P(l->radial_next, cd_loop_mdisp_offset));
}
else {
mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next->next, cd_loop_mdisp_offset);
mdl2 = static_cast<MDisps *>(
BM_ELEM_CD_GET_VOID_P(l->radial_next->next, cd_loop_mdisp_offset));
}
sides = (int)sqrt(mdl1->totdisp);
@ -685,10 +690,12 @@ void BM_loop_interp_from_face(
{
BMLoop *l_iter;
BMLoop *l_first;
const void **vblocks = do_vertex ? BLI_array_alloca(vblocks, f_src->len) : NULL;
const void **blocks = BLI_array_alloca(blocks, f_src->len);
float(*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
float *w = BLI_array_alloca(w, f_src->len);
const void **vblocks = do_vertex ?
static_cast<const void **>(BLI_array_alloca(vblocks, f_src->len)) :
nullptr;
const void **blocks = static_cast<const void **>(BLI_array_alloca(blocks, f_src->len));
float(*cos_2d)[2] = static_cast<float(*)[2]>(BLI_array_alloca(cos_2d, f_src->len));
float *w = static_cast<float *>(BLI_array_alloca(w, f_src->len));
float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
float co[2];
@ -723,9 +730,9 @@ void BM_loop_interp_from_face(
/* interpolate */
interp_weights_poly_v2(w, cos_2d, f_src->len, co);
CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, f_src->len, l_dst->head.data);
CustomData_bmesh_interp(&bm->ldata, blocks, w, nullptr, f_src->len, l_dst->head.data);
if (do_vertex) {
CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, f_src->len, l_dst->v->head.data);
CustomData_bmesh_interp(&bm->vdata, vblocks, w, nullptr, f_src->len, l_dst->v->head.data);
}
if (do_multires) {
@ -737,9 +744,9 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src)
{
BMLoop *l_iter;
BMLoop *l_first;
const void **blocks = BLI_array_alloca(blocks, f_src->len);
float(*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
float *w = BLI_array_alloca(w, f_src->len);
const void **blocks = static_cast<const void **>(BLI_array_alloca(blocks, f_src->len));
float(*cos_2d)[2] = static_cast<float(*)[2]>(BLI_array_alloca(cos_2d, f_src->len));
float *w = static_cast<float *>(BLI_array_alloca(w, f_src->len));
float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
float co[2];
@ -758,7 +765,7 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src)
/* interpolate */
interp_weights_poly_v2(w, cos_2d, f_src->len, co);
CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, f_src->len, v_dst->head.data);
CustomData_bmesh_interp(&bm->vdata, blocks, w, nullptr, f_src->len, v_dst->head.data);
}
static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
@ -773,7 +780,7 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
CustomData_bmesh_init_pool(data, bm->totvert, BM_VERT);
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
block = NULL;
block = nullptr;
CustomData_bmesh_set_default(data, &block);
CustomData_bmesh_copy_data(olddata, data, eve->head.data, &block);
CustomData_bmesh_free_block(olddata, &eve->head.data);
@ -786,7 +793,7 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
CustomData_bmesh_init_pool(data, bm->totedge, BM_EDGE);
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
block = NULL;
block = nullptr;
CustomData_bmesh_set_default(data, &block);
CustomData_bmesh_copy_data(olddata, data, eed->head.data, &block);
CustomData_bmesh_free_block(olddata, &eed->head.data);
@ -801,7 +808,7 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
CustomData_bmesh_init_pool(data, bm->totloop, BM_LOOP);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
block = NULL;
block = nullptr;
CustomData_bmesh_set_default(data, &block);
CustomData_bmesh_copy_data(olddata, data, l->head.data, &block);
CustomData_bmesh_free_block(olddata, &l->head.data);
@ -815,7 +822,7 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
CustomData_bmesh_init_pool(data, bm->totface, BM_FACE);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
block = NULL;
block = nullptr;
CustomData_bmesh_set_default(data, &block);
CustomData_bmesh_copy_data(olddata, data, efa->head.data, &block);
CustomData_bmesh_free_block(olddata, &efa->head.data);
@ -838,11 +845,13 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
{
CustomData olddata = *data;
olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
olddata.layers = (olddata.layers) ?
static_cast<CustomDataLayer *>(MEM_dupallocN(olddata.layers)) :
nullptr;
/* The pool is now owned by `olddata` and must not be shared. */
data->pool = NULL;
data->pool = nullptr;
CustomData_add_layer(data, type, CD_SET_DEFAULT, 0);
CustomData_add_layer(data, eCustomDataType(type), CD_SET_DEFAULT, 0);
update_data_blocks(bm, &olddata, data);
if (olddata.layers) {
@ -853,11 +862,13 @@ void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name)
{
CustomData olddata = *data;
olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
olddata.layers = (olddata.layers) ?
static_cast<CustomDataLayer *>(MEM_dupallocN(olddata.layers)) :
nullptr;
/* The pool is now owned by `olddata` and must not be shared. */
data->pool = NULL;
data->pool = nullptr;
CustomData_add_layer_named(data, type, CD_SET_DEFAULT, 0, name);
CustomData_add_layer_named(data, eCustomDataType(type), CD_SET_DEFAULT, 0, name);
update_data_blocks(bm, &olddata, data);
if (olddata.layers) {
@ -867,7 +878,7 @@ void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *
void BM_data_layer_ensure_named(BMesh *bm, CustomData *data, int type, const char *name)
{
if (CustomData_get_named_layer_index(data, type, name) == -1) {
if (CustomData_get_named_layer_index(data, eCustomDataType(type), name) == -1) {
BM_data_layer_add_named(bm, data, type, name);
}
}
@ -923,11 +934,13 @@ void BM_uv_map_ensure_pin_attr(BMesh *bm, const char *uv_map_name)
void BM_data_layer_free(BMesh *bm, CustomData *data, int type)
{
CustomData olddata = *data;
olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
olddata.layers = (olddata.layers) ?
static_cast<CustomDataLayer *>(MEM_dupallocN(olddata.layers)) :
nullptr;
/* The pool is now owned by `olddata` and must not be shared. */
data->pool = NULL;
data->pool = nullptr;
const bool had_layer = CustomData_free_layer_active(data, type, 0);
const bool had_layer = CustomData_free_layer_active(data, eCustomDataType(type), 0);
/* Assert because its expensive to realloc - better not do if layer isn't present. */
BLI_assert(had_layer != false);
UNUSED_VARS_NDEBUG(had_layer);
@ -941,9 +954,11 @@ void BM_data_layer_free(BMesh *bm, CustomData *data, int type)
bool BM_data_layer_free_named(BMesh *bm, CustomData *data, const char *name)
{
CustomData olddata = *data;
olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
olddata.layers = (olddata.layers) ?
static_cast<CustomDataLayer *>(MEM_dupallocN(olddata.layers)) :
nullptr;
/* The pool is now owned by `olddata` and must not be shared. */
data->pool = NULL;
data->pool = nullptr;
const bool had_layer = CustomData_free_layer_named(data, name, 0);
@ -965,12 +980,17 @@ bool BM_data_layer_free_named(BMesh *bm, CustomData *data, const char *name)
void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n)
{
CustomData olddata = *data;
olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
olddata.layers = (olddata.layers) ?
static_cast<CustomDataLayer *>(MEM_dupallocN(olddata.layers)) :
nullptr;
/* The pool is now owned by `olddata` and must not be shared. */
data->pool = NULL;
data->pool = nullptr;
const bool had_layer = CustomData_free_layer(
data, type, 0, CustomData_get_layer_index_n(data, type, n));
data,
eCustomDataType(type),
0,
CustomData_get_layer_index_n(data, eCustomDataType(type), n));
/* Assert because its expensive to realloc - better not do if layer isn't present. */
BLI_assert(had_layer != false);
UNUSED_VARS_NDEBUG(had_layer);
@ -989,24 +1009,24 @@ void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int ds
BMVert *eve;
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
void *ptr = CustomData_bmesh_get_n(data, eve->head.data, type, src_n);
CustomData_bmesh_set_n(data, eve->head.data, type, dst_n, ptr);
void *ptr = CustomData_bmesh_get_n(data, eve->head.data, eCustomDataType(type), src_n);
CustomData_bmesh_set_n(data, eve->head.data, eCustomDataType(type), dst_n, ptr);
}
}
else if (&bm->edata == data) {
BMEdge *eed;
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
void *ptr = CustomData_bmesh_get_n(data, eed->head.data, type, src_n);
CustomData_bmesh_set_n(data, eed->head.data, type, dst_n, ptr);
void *ptr = CustomData_bmesh_get_n(data, eed->head.data, eCustomDataType(type), src_n);
CustomData_bmesh_set_n(data, eed->head.data, eCustomDataType(type), dst_n, ptr);
}
}
else if (&bm->pdata == data) {
BMFace *efa;
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
void *ptr = CustomData_bmesh_get_n(data, efa->head.data, type, src_n);
CustomData_bmesh_set_n(data, efa->head.data, type, dst_n, ptr);
void *ptr = CustomData_bmesh_get_n(data, efa->head.data, eCustomDataType(type), src_n);
CustomData_bmesh_set_n(data, efa->head.data, eCustomDataType(type), dst_n, ptr);
}
}
else if (&bm->ldata == data) {
@ -1016,8 +1036,8 @@ void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int ds
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
void *ptr = CustomData_bmesh_get_n(data, l->head.data, type, src_n);
CustomData_bmesh_set_n(data, l->head.data, type, dst_n, ptr);
void *ptr = CustomData_bmesh_get_n(data, l->head.data, eCustomDataType(type), src_n);
CustomData_bmesh_set_n(data, l->head.data, eCustomDataType(type), dst_n, ptr);
}
}
}
@ -1029,13 +1049,15 @@ void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int ds
float BM_elem_float_data_get(CustomData *cd, void *element, int type)
{
const float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type);
const float *f = static_cast<const float *>(
CustomData_bmesh_get(cd, ((BMHeader *)element)->data, eCustomDataType(type)));
return f ? *f : 0.0f;
}
void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val)
{
float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type);
float *f = static_cast<float *>(
CustomData_bmesh_get(cd, ((BMHeader *)element)->data, eCustomDataType(type)));
if (f) {
*f = val;
}
@ -1117,8 +1139,9 @@ static void bm_loop_walk_data(struct LoopWalkCtx *lwc, BMLoop *l_walk)
{
int i;
BLI_assert(CustomData_data_equals(
lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_walk, lwc->cd_layer_offset)));
BLI_assert(CustomData_data_equals(eCustomDataType(lwc->type),
lwc->data_ref,
BM_ELEM_CD_GET_VOID_P(l_walk, lwc->cd_layer_offset)));
BLI_assert(BM_elem_flag_test(l_walk, BM_ELEM_INTERNAL_TAG));
bm_loop_walk_add(lwc, l_walk);
@ -1132,8 +1155,9 @@ static void bm_loop_walk_data(struct LoopWalkCtx *lwc, BMLoop *l_walk)
}
BLI_assert(l_other->v == l_walk->v);
if (BM_elem_flag_test(l_other, BM_ELEM_INTERNAL_TAG)) {
if (CustomData_data_equals(
lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_other, lwc->cd_layer_offset)))
if (CustomData_data_equals(eCustomDataType(lwc->type),
lwc->data_ref,
BM_ELEM_CD_GET_VOID_P(l_other, lwc->cd_layer_offset)))
{
bm_loop_walk_data(lwc, l_other);
}
@ -1146,7 +1170,7 @@ LinkNode *BM_vert_loop_groups_data_layer_create(
BMesh *bm, BMVert *v, const int layer_n, const float *loop_weights, MemArena *arena)
{
struct LoopWalkCtx lwc;
LinkNode *groups = NULL;
LinkNode *groups = nullptr;
BMLoop *l;
BMIter liter;
int loop_num;
@ -1166,13 +1190,14 @@ LinkNode *BM_vert_loop_groups_data_layer_create(
bm->elem_index_dirty |= BM_LOOP;
lwc.data_len = 0;
lwc.data_array = BLI_memarena_alloc(lwc.arena, sizeof(void *) * loop_num);
lwc.data_index_array = BLI_memarena_alloc(lwc.arena, sizeof(int) * loop_num);
lwc.weight_array = BLI_memarena_alloc(lwc.arena, sizeof(float) * loop_num);
lwc.data_array = static_cast<void **>(BLI_memarena_alloc(lwc.arena, sizeof(void *) * loop_num));
lwc.data_index_array = static_cast<int *>(BLI_memarena_alloc(lwc.arena, sizeof(int) * loop_num));
lwc.weight_array = static_cast<float *>(BLI_memarena_alloc(lwc.arena, sizeof(float) * loop_num));
BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
if (BM_elem_flag_test(l, BM_ELEM_INTERNAL_TAG)) {
struct LoopGroupCD *lf = BLI_memarena_alloc(lwc.arena, sizeof(*lf));
struct LoopGroupCD *lf = static_cast<LoopGroupCD *>(
BLI_memarena_alloc(lwc.arena, sizeof(*lf)));
int len_prev = lwc.data_len;
lwc.data_ref = BM_ELEM_CD_GET_VOID_P(l, lwc.cd_layer_offset);
@ -1208,7 +1233,7 @@ static void bm_vert_loop_groups_data_layer_merge__single(BMesh *bm,
int layer_n,
void *data_tmp)
{
struct LoopGroupCD *lf = lf_p;
struct LoopGroupCD *lf = static_cast<LoopGroupCD *>(lf_p);
const int type = bm->ldata.layers[layer_n].type;
int i;
const float *data_weights;
@ -1216,23 +1241,23 @@ static void bm_vert_loop_groups_data_layer_merge__single(BMesh *bm,
data_weights = lf->data_weights;
CustomData_bmesh_interp_n(
&bm->ldata, (const void **)lf->data, data_weights, NULL, lf->data_len, data_tmp, layer_n);
&bm->ldata, (const void **)lf->data, data_weights, nullptr, lf->data_len, data_tmp, layer_n);
for (i = 0; i < lf->data_len; i++) {
CustomData_copy_elements(type, data_tmp, lf->data[i], 1);
CustomData_copy_elements(eCustomDataType(type), data_tmp, lf->data[i], 1);
}
}
static void bm_vert_loop_groups_data_layer_merge_weights__single(
BMesh *bm, void *lf_p, const int layer_n, void *data_tmp, const float *loop_weights)
{
struct LoopGroupCD *lf = lf_p;
struct LoopGroupCD *lf = static_cast<LoopGroupCD *>(lf_p);
const int type = bm->ldata.layers[layer_n].type;
int i;
const float *data_weights;
/* re-weight */
float *temp_weights = BLI_array_alloca(temp_weights, lf->data_len);
float *temp_weights = static_cast<float *>(BLI_array_alloca(temp_weights, lf->data_len));
float weight_accum = 0.0f;
for (i = 0; i < lf->data_len; i++) {
@ -1250,17 +1275,17 @@ static void bm_vert_loop_groups_data_layer_merge_weights__single(
}
CustomData_bmesh_interp_n(
&bm->ldata, (const void **)lf->data, data_weights, NULL, lf->data_len, data_tmp, layer_n);
&bm->ldata, (const void **)lf->data, data_weights, nullptr, lf->data_len, data_tmp, layer_n);
for (i = 0; i < lf->data_len; i++) {
CustomData_copy_elements(type, data_tmp, lf->data[i], 1);
CustomData_copy_elements(eCustomDataType(type), data_tmp, lf->data[i], 1);
}
}
void BM_vert_loop_groups_data_layer_merge(BMesh *bm, LinkNode *groups, const int layer_n)
{
const int type = bm->ldata.layers[layer_n].type;
const int size = CustomData_sizeof(type);
const int size = CustomData_sizeof(eCustomDataType(type));
void *data_tmp = alloca(size);
do {
@ -1274,7 +1299,7 @@ void BM_vert_loop_groups_data_layer_merge_weights(BMesh *bm,
const float *loop_weights)
{
const int type = bm->ldata.layers[layer_n].type;
const int size = CustomData_sizeof(type);
const int size = CustomData_sizeof(eCustomDataType(type));
void *data_tmp = alloca(size);
do {

View File

@ -62,7 +62,6 @@ enum {
SIMFACE_NORMAL,
SIMFACE_COPLANAR,
SIMFACE_SMOOTH,
SIMFACE_FACEMAP,
SIMFACE_FREESTYLE,
};

View File

@ -109,7 +109,7 @@ typedef struct PathLinkState {
} PathLinkState;
/* -------------------------------------------------------------------- */
/** \name Min Dist Dir Util
/** \name Min Dist Dir Utilities
*
* Simply getting the closest intersecting vert/edge is _not_ good enough. see #43792
* we need to get the closest in both directions since the absolute closest may be a dead-end.

View File

@ -766,7 +766,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
vert_coords = BLI_ghash_ptr_new(__func__);
}
/* util macros */
/* Utility macros. */
#define VERT_ORIG_STORE(_v) \
{ \
float *_co = BLI_memarena_alloc(vert_coords_orig, sizeof(float[3])); \

View File

@ -4,6 +4,7 @@
#include "COM_KuwaharaNode.h"
#include "COM_ConvolutionFilterOperation.h"
#include "COM_FastGaussianBlurOperation.h"
#include "COM_KuwaharaAnisotropicOperation.h"
#include "COM_KuwaharaClassicOperation.h"

View File

@ -104,7 +104,7 @@ void KuwaharaAnisotropicOperation::execute_pixel_sampled(float output[4],
int dx2 = int(sx * (cos(theta) * dx - sin(theta) * dy));
int dy2 = int(sy * (sin(theta) * dx + cos(theta) * dy));
/* Clamp image to avoid artefacts at borders. */
/* Clamp image to avoid artifacts at borders. */
const int xx = math::clamp(int(x) + dx2, 0, width - 1);
const int yy = math::clamp(int(y) + dy2, 0, height - 1);
@ -117,9 +117,9 @@ void KuwaharaAnisotropicOperation::execute_pixel_sampled(float output[4],
float color[4];
image_reader_->read(color, xx, yy, nullptr);
const double v = color[ch];
/* todo(zazizizou): only compute lum once per region */
/* TODO(@zazizizou): only compute lum once per region */
const float lum = IMB_colormanagement_get_luminance(color);
/* todo(zazizizou): only compute mean for the selected region */
/* TODO(@zazizizou): only compute mean for the selected region */
mean[t] += g * v;
sum[t] += g * lum;
var[t] += g * lum * lum;
@ -155,7 +155,7 @@ void KuwaharaAnisotropicOperation::execute_pixel_sampled(float output[4],
void KuwaharaAnisotropicOperation::set_kernel_size(int kernel_size)
{
/* Filter will be split into n_div.
* Add n_div / 2 to avoid artefacts such as random black pixels in image. */
* Add n_div / 2 to avoid artifacts such as random black pixels in image. */
kernel_size_ = kernel_size + n_div_ / 2;
}
@ -244,7 +244,7 @@ void KuwaharaAnisotropicOperation::update_memory_buffer_partial(MemoryBuffer *ou
int dx2 = int(sx * (cos(theta) * dx - sin(theta) * dy));
int dy2 = int(sy * (sin(theta) * dx + cos(theta) * dy));
/* Clamp image to avoid artefacts at borders. */
/* Clamp image to avoid artifacts at borders. */
const int xx = math::clamp(x + dx2, 0, width - 1);
const int yy = math::clamp(y + dy2, 0, height - 1);
@ -257,9 +257,9 @@ void KuwaharaAnisotropicOperation::update_memory_buffer_partial(MemoryBuffer *ou
const double v = image->get_value(xx, yy, ch);
float color[4];
image->read_elem(xx, yy, color);
/* TODO(zazizizou): only compute lum once per region. */
/* TODO(@zazizizou): only compute lum once per region. */
const float lum = IMB_colormanagement_get_luminance(color);
/* TODO(zazizizou): only compute mean for the selected region. */
/* TODO(@zazizizou): only compute mean for the selected region. */
mean[t] += g * v;
sum[t] += g * lum;
var[t] += g * lum * lum;

View File

@ -101,6 +101,11 @@ void KuwaharaClassicOperation::execute_pixel_sampled(float output[4],
}
output[ch] = mean[min_index];
}
/* No changes for alpha channel. */
float tmp[4];
image_reader_->read_sampled(tmp, x, y, sampler);
output[3] = tmp[3];
}
void KuwaharaClassicOperation::set_kernel_size(int kernel_size)

View File

@ -45,9 +45,14 @@ class Context {
/* Get the node tree used for compositing. */
virtual const bNodeTree &get_node_tree() const = 0;
/* True if compositor should do write file outputs, false if only running for viewing. */
/* True if the compositor should write file outputs, false otherwise. */
virtual bool use_file_output() const = 0;
/* True if the compositor should write the composite output, otherwise, the compositor is assumed
* to not support the composite output and just displays its viewer output. In that case, the
* composite output will be used as a fallback viewer if no other viewer exists */
virtual bool use_composite_output() const = 0;
/* True if color management should be used for texture evaluation. */
virtual bool use_texture_color_management() const = 0;
@ -66,10 +71,14 @@ class Context {
* region. */
virtual rcti get_compositing_region() const = 0;
/* Get the texture representing the output where the result of the compositor should be
* written. This should be called by output nodes to get their target texture. */
/* Get the texture where the result of the compositor should be written. This should be called by
* the composite output node to get its target texture. */
virtual GPUTexture *get_output_texture() = 0;
/* Get the texture where the result of the compositor viewer should be written. This should be
* called by viewer output nodes to get their target texture. */
virtual GPUTexture *get_viewer_output_texture() = 0;
/* Get the texture where the given render pass is stored. This should be called by the Render
* Layer node to populate its outputs. */
virtual GPUTexture *get_input_texture(int view_layer, const char *pass_name) = 0;

View File

@ -8,6 +8,8 @@
#include "NOD_derived_node_tree.hh"
#include "COM_context.hh"
namespace blender::realtime_compositor {
using namespace nodes::derived_node_tree_types;
@ -18,6 +20,6 @@ using Schedule = VectorSet<DNode>;
/* Computes the execution schedule of the node tree. This is essentially a post-order depth first
* traversal of the node tree from the output node to the leaf input nodes, with informed order of
* traversal of dependencies based on a heuristic estimation of the number of needed buffers. */
Schedule compute_schedule(const DerivedNodeTree &tree);
Schedule compute_schedule(const Context &context, const DerivedNodeTree &tree);
} // namespace blender::realtime_compositor

View File

@ -72,7 +72,7 @@ void Evaluator::compile_and_evaluate()
return;
}
const Schedule schedule = compute_schedule(*derived_node_tree_);
const Schedule schedule = compute_schedule(context_, *derived_node_tree_);
CompileState compile_state(schedule);

View File

@ -13,6 +13,7 @@
#include "BKE_node.hh"
#include "BKE_node_runtime.hh"
#include "COM_context.hh"
#include "COM_scheduler.hh"
#include "COM_utilities.hh"
@ -72,55 +73,88 @@ static const DTreeContext *find_active_context(const DerivedNodeTree &tree)
return find_active_context_recursive(&tree.root_context(), NODE_INSTANCE_KEY_BASE);
}
/* Return the output node which is marked as NODE_DO_OUTPUT. If multiple types of output nodes are
* marked, then the preference will be CMP_NODE_VIEWER > CMP_NODE_SPLITVIEWER > CMP_NODE_COMPOSITE.
* If no output node exists, a null node will be returned. */
static DNode find_output_in_context(const DTreeContext *context)
/* Add the viewer node which is marked as NODE_DO_OUTPUT in the given context to the given stack.
* If multiple types of viewer nodes are marked, then the preference will be CMP_NODE_VIEWER >
* CMP_NODE_SPLITVIEWER. If no viewer nodes were found, composite nodes can be added as a fallback
* viewer node. */
static bool add_viewer_nodes_in_context(const DTreeContext *context, Stack<DNode> &node_stack)
{
const bNodeTree &tree = context->btree();
for (const bNode *node : tree.nodes_by_type("CompositorNodeViewer")) {
for (const bNode *node : context->btree().nodes_by_type("CompositorNodeViewer")) {
if (node->flag & NODE_DO_OUTPUT) {
return DNode(context, node);
node_stack.push(DNode(context, node));
return true;
}
}
for (const bNode *node : tree.nodes_by_type("CompositorNodeSplitViewer")) {
for (const bNode *node : context->btree().nodes_by_type("CompositorNodeSplitViewer")) {
if (node->flag & NODE_DO_OUTPUT) {
return DNode(context, node);
node_stack.push(DNode(context, node));
return true;
}
}
for (const bNode *node : tree.nodes_by_type("CompositorNodeComposite")) {
/* The active Composite node was already added, no need to add it again, see the next block. */
if (!node_stack.is_empty() && node_stack.peek()->type == CMP_NODE_COMPOSITE) {
return false;
}
/* No active viewers exist in this context, try to add the Composite node as a fallback viewer if
* it was not already added. */
for (const bNode *node : context->btree().nodes_by_type("CompositorNodeComposite")) {
if (node->flag & NODE_DO_OUTPUT) {
return DNode(context, node);
node_stack.push(DNode(context, node));
return true;
}
}
return DNode();
return false;
}
/* Compute the output node whose result should be computed. This node is the output node that
* satisfies the requirements in the find_output_in_context function. First, the active context is
* searched for an output node, if non was found, the root context is search. For more information
* on what contexts mean here, see the find_active_context function. */
static DNode compute_output_node(const DerivedNodeTree &tree)
/* Add the output nodes whose result should be computed to the given stack. This includes File
* Output, Composite, and Viewer nodes. Viewer nodes are a special case, as only the nodes that
* satisfies the requirements in the add_viewer_nodes_in_context function are added. First, the
* active context is searched for viewer nodes, if non were found, the root context is searched.
* For more information on what contexts mean here, see the find_active_context function. */
static void add_output_nodes(const Context &context,
const DerivedNodeTree &tree,
Stack<DNode> &node_stack)
{
const DTreeContext &root_context = tree.root_context();
/* Only add File Output nodes if the context supports them. */
if (context.use_file_output()) {
for (const bNode *node : root_context.btree().nodes_by_type("CompositorNodeOutputFile")) {
node_stack.push(DNode(&root_context, node));
}
}
/* Only add the Composite output node if the context supports composite outputs. The active
* Composite node may still be added as a fallback viewer output below. */
if (context.use_composite_output()) {
for (const bNode *node : root_context.btree().nodes_by_type("CompositorNodeComposite")) {
if (node->flag & NODE_DO_OUTPUT) {
node_stack.push(DNode(&root_context, node));
break;
}
}
}
const DTreeContext *active_context = find_active_context(tree);
const bool viewer_was_added = add_viewer_nodes_in_context(active_context, node_stack);
const DNode node = find_output_in_context(active_context);
if (node) {
return node;
/* An active viewer was added, no need to search further. */
if (viewer_was_added) {
return;
}
/* If the active context is the root one and no output node was found, we consider this node tree
* to have no output node, even if one of the non-active descendants have an output node. */
/* If the active context is the root one and no viewer nodes were found, we consider this node
* tree to have no viewer nodes, even if one of the non-active descendants have viewer nodes. */
if (active_context->is_root()) {
return DNode();
return;
}
/* The active context doesn't have an output node, search in the root context as a fallback. */
return find_output_in_context(&tree.root_context());
/* The active context doesn't have a viewer node, search in the root context as a fallback. */
add_viewer_nodes_in_context(&tree.root_context(), node_stack);
}
/* A type representing a mapping that associates each node with a heuristic estimation of the
@ -177,12 +211,12 @@ using NeededBuffers = Map<DNode, int>;
* implementation because it rarely affects the output and is done by very few nodes.
* - The compiler may decide to compiler the schedule differently depending on runtime information
* which we can merely speculate at scheduling-time as described above. */
static NeededBuffers compute_number_of_needed_buffers(DNode output_node)
static NeededBuffers compute_number_of_needed_buffers(Stack<DNode> &output_nodes)
{
NeededBuffers needed_buffers;
/* A stack of nodes used to traverse the node tree starting from the output node. */
Stack<DNode> node_stack = {output_node};
/* A stack of nodes used to traverse the node tree starting from the output nodes. */
Stack<DNode> node_stack = output_nodes;
/* Traverse the node tree in a post order depth first manner and compute the number of needed
* buffers for each node. Post order traversal guarantee that all the node dependencies of each
@ -301,23 +335,23 @@ static NeededBuffers compute_number_of_needed_buffers(DNode output_node)
* doesn't always guarantee an optimal evaluation order, as the optimal evaluation order is very
* difficult to compute, however, this method works well in most cases. Moreover it assumes that
* all buffers will have roughly the same size, which may not always be the case. */
Schedule compute_schedule(const DerivedNodeTree &tree)
Schedule compute_schedule(const Context &context, const DerivedNodeTree &tree)
{
Schedule schedule;
/* Compute the output node whose result should be computed. */
const DNode output_node = compute_output_node(tree);
/* A stack of nodes used to traverse the node tree starting from the output nodes. */
Stack<DNode> node_stack;
/* No output node, the node tree has no effect, return an empty schedule. */
if (!output_node) {
/* Add the output nodes whose result should be computed to the stack. */
add_output_nodes(context, tree, node_stack);
/* No output nodes, the node tree has no effect, return an empty schedule. */
if (node_stack.is_empty()) {
return schedule;
}
/* Compute the number of buffers needed by each node connected to the output. */
const NeededBuffers needed_buffers = compute_number_of_needed_buffers(output_node);
/* A stack of nodes used to traverse the node tree starting from the output node. */
Stack<DNode> node_stack = {output_node};
/* Compute the number of buffers needed by each node connected to the outputs. */
const NeededBuffers needed_buffers = compute_number_of_needed_buffers(node_stack);
/* Traverse the node tree in a post order depth first manner, scheduling the nodes in an order
* informed by the number of buffers needed by each node. Post order traversal guarantee that all
@ -360,7 +394,8 @@ Schedule compute_schedule(const DerivedNodeTree &tree)
int insertion_position = 0;
for (int i = 0; i < sorted_dependency_nodes.size(); i++) {
if (needed_buffers.lookup(doutput.node()) >
needed_buffers.lookup(sorted_dependency_nodes[i])) {
needed_buffers.lookup(sorted_dependency_nodes[i]))
{
insertion_position++;
}
else {

View File

@ -68,6 +68,14 @@ class Context : public realtime_compositor::Context {
return false;
}
/* The viewport compositor doesn't really support the composite output, it only displays the
* viewer output in the viewport. Settings this to false will make the compositor use the
* composite output as fallback viewer if no other viewer exists. */
bool use_composite_output() const override
{
return false;
}
bool use_texture_color_management() const override
{
return BKE_scene_check_color_management_enabled(DRW_context_state_get()->scene);
@ -145,6 +153,11 @@ class Context : public realtime_compositor::Context {
return DRW_viewport_texture_list_get()->color;
}
GPUTexture *get_viewer_output_texture() override
{
return DRW_viewport_texture_list_get()->color;
}
GPUTexture *get_input_texture(int view_layer, const char *pass_name) override
{
if (view_layer == 0 && STREQ(pass_name, RE_PASSNAME_COMBINED)) {

View File

@ -184,7 +184,7 @@ static void drw_shgroup_uniform_create_ex(DRWShadingGroup *shgroup,
/* Happens on first uniform or if chunk is full. */
if (!unichunk || unichunk->uniform_used == unichunk->uniform_len) {
unichunk = static_cast<DRWUniformChunk *>(BLI_memblock_alloc(DST.vmempool->uniforms));
unichunk->uniform_len = ARRAY_SIZE(shgroup->uniforms->uniforms);
unichunk->uniform_len = BOUNDED_ARRAY_TYPE_SIZE<decltype(shgroup->uniforms->uniforms)>();
unichunk->uniform_used = 0;
BLI_LINKS_PREPEND(shgroup->uniforms, unichunk);
}

View File

@ -566,13 +566,14 @@ bool ANIM_animdata_can_have_greasepencil(const eAnimCont_Types type)
((filter_mode & ANIMFILTER_SEL) && test_func) || \
((filter_mode & ANIMFILTER_UNSEL) && test_func == 0))
/* quick macro to test if an anim-channel (F-Curve) is selected ok for editing purposes
* - _SELEDIT means that only selected curves will have visible+editable keyframes
/**
* Quick macro to test if an anim-channel (F-Curve) is selected ok for editing purposes
* - `*_SELEDIT` means that only selected curves will have visible+editable key-frames.
*
* checks here work as follows:
* 1) seledit off - don't need to consider the implications of this option
* 2) foredit off - we're not considering editing, so channel is ok still
* 3) test_func (i.e. selection test) - only if selected, this test will pass
* 1) SELEDIT off - don't need to consider the implications of this option.
* 2) FOREDIT off - we're not considering editing, so channel is ok still.
* 3) test_func (i.e. selection test) - only if selected, this test will pass.
*/
#define ANIMCHANNEL_SELEDITOK(test_func) \
(!(filter_mode & ANIMFILTER_SELEDIT) || !(filter_mode & ANIMFILTER_FOREDIT) || (test_func))
@ -1194,7 +1195,7 @@ static bool skip_fcurve_with_name(
*/
static bool fcurve_has_errors(const FCurve *fcu)
{
/* F-Curve disabled - path eval error */
/* F-Curve disabled (path evaluation error). */
if (fcu->flag & FCURVE_DISABLED) {
return true;
}

View File

@ -265,6 +265,10 @@ static bool need_extra_redraw_after_scrubbing_ends(bContext *C)
* scrubbing, the actual result should be shown again. */
return true;
}
Scene *scene = CTX_data_scene(C);
if (scene->eevee.flag & SCE_EEVEE_TAA_REPROJECTION) {
return true;
}
wmWindowManager *wm = CTX_wm_manager(C);
Object *object = CTX_data_active_object(C);
if (object && object->type == OB_GPENCIL_LEGACY) {

View File

@ -45,9 +45,9 @@ set(SRC
ED_asset_catalog.h
ED_asset_catalog.hh
ED_asset_filter.h
ED_asset_filter.hh
ED_asset_handle.h
ED_asset_import.h
ED_asset_import.hh
ED_asset_indexer.h
ED_asset_library.h
ED_asset_list.h

View File

@ -10,12 +10,11 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct AssetFilterSettings;
struct AssetHandle;
namespace blender::asset_system {
class AssetRepresentation;
}
/**
* Compare \a asset against the settings of \a filter.
@ -29,9 +28,5 @@ struct AssetHandle;
* \returns True if the asset should be visible with these filter settings (parameters match).
* Otherwise returns false (mismatch).
*/
bool ED_asset_filter_matches_asset(const struct AssetFilterSettings *filter,
const struct AssetHandle *asset);
#ifdef __cplusplus
}
#endif
bool ED_asset_filter_matches_asset(const AssetFilterSettings *filter,
const blender::asset_system::AssetRepresentation &asset);

View File

@ -34,24 +34,7 @@ void ED_asset_handle_get_full_library_path(
/* `1024` for #FILE_MAX,
* rely on warnings to let us know if this gets out of sync. */
char r_full_lib_path[1024]);
bool ED_asset_handle_get_use_relative_path(const struct AssetHandle *asset);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
# include "BLI_string_ref.hh"
# include <optional>
# include "BLI_string_ref.hh"
/** The asset library may have an import method (e.g. append vs. link) defined to use. If so, this
* returns it. Otherwise a reasonable method should be used, usually "Append (Reuse Data)". */
std::optional<eAssetImportMethod> ED_asset_handle_get_import_method(
const struct AssetHandle *asset);
blender::StringRefNull ED_asset_handle_get_library_relative_identifier(const AssetHandle &asset);
#endif

View File

@ -10,16 +10,11 @@
#include "DNA_ID_enums.h"
struct AssetRepresentation;
struct Main;
#ifdef __cplusplus
extern "C" {
#endif
namespace blender::asset_system {
class AssetRepresentation;
}
struct ID *ED_asset_get_local_id_from_asset_or_append_and_reuse(
struct Main *bmain, const struct AssetRepresentation *asset_c_ptr, ID_Type idtype);
#ifdef __cplusplus
}
#endif
Main *bmain, const blender::asset_system::AssetRepresentation &asset, ID_Type idtype);

View File

@ -10,6 +10,12 @@
#include "DNA_asset_types.h"
#ifdef __cplusplus
namespace blender::asset_system {
class AssetRepresentation;
}
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -52,8 +58,12 @@ void ED_assetlist_storage_id_remap(struct ID *id_old, struct ID *id_new);
*/
void ED_assetlist_storage_exit(void);
AssetHandle ED_assetlist_asset_get_by_index(const AssetLibraryReference *library_reference,
int asset_index);
AssetHandle ED_assetlist_asset_handle_get_by_index(const AssetLibraryReference *library_reference,
int asset_index);
#ifdef __cplusplus
blender::asset_system::AssetRepresentation *ED_assetlist_asset_get_by_index(
const AssetLibraryReference &library_reference, int asset_index);
#endif
struct ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle);

View File

@ -17,7 +17,8 @@ struct AssetLibraryReference;
namespace blender::asset_system {
class AssetLibrary;
}
class AssetRepresentation;
} // namespace blender::asset_system
/**
* Get the asset library being read into an asset-list and identified using \a library_reference.
@ -31,9 +32,13 @@ blender::asset_system::AssetLibrary *ED_assetlist_library_get_once_available(
const AssetLibraryReference &library_reference);
/* Can return false to stop iterating. */
using AssetListIterFn = blender::FunctionRef<bool(AssetHandle)>;
using AssetListHandleIterFn = blender::FunctionRef<bool(AssetHandle)>;
using AssetListIterFn = blender::FunctionRef<bool(blender::asset_system::AssetRepresentation &)>;
/**
* \warning Never keep the asset handle passed to \a fn outside of \a fn's scope. While iterating,
* the file data wrapped by the asset handle can be freed, since the file cache has a maximum size.
*/
void ED_assetlist_iterate(const AssetLibraryReference &library_reference,
AssetListHandleIterFn fn);
void ED_assetlist_iterate(const AssetLibraryReference &library_reference, AssetListIterFn fn);

View File

@ -6,18 +6,22 @@
* \ingroup edasset
*/
#include "AS_asset_representation.hh"
#include "BKE_idtype.h"
#include "BLI_listbase.h"
#include "DNA_asset_types.h"
#include "ED_asset_filter.h"
#include "ED_asset_handle.h"
#include "ED_asset_filter.hh"
bool ED_asset_filter_matches_asset(const AssetFilterSettings *filter, const AssetHandle *asset)
using namespace blender;
bool ED_asset_filter_matches_asset(const AssetFilterSettings *filter,
const asset_system::AssetRepresentation &asset)
{
ID_Type asset_type = ED_asset_handle_get_id_type(asset);
ID_Type asset_type = asset.get_id_type();
uint64_t asset_id_filter = BKE_idtype_idcode_to_idfilter(asset_type);
if (filter->id_types && (filter->id_types & asset_id_filter) == 0) {
@ -25,10 +29,10 @@ bool ED_asset_filter_matches_asset(const AssetFilterSettings *filter, const Asse
}
/* Not very efficient (O(n^2)), could be improved quite a bit. */
LISTBASE_FOREACH (const AssetTag *, filter_tag, &filter->tags) {
AssetMetaData *asset_data = ED_asset_handle_get_metadata(asset);
AssetMetaData &asset_data = asset.get_metadata();
AssetTag *matched_tag = (AssetTag *)BLI_findstring(
&asset_data->tags, filter_tag->name, offsetof(AssetTag, name));
&asset_data.tags, filter_tag->name, offsetof(AssetTag, name));
if (matched_tag == nullptr) {
return false;
}

View File

@ -36,14 +36,14 @@ AssetMetaData *ED_asset_handle_get_metadata(const AssetHandle *asset_handle)
return AS_asset_representation_metadata_get(asset_handle->file_data->asset);
}
ID *ED_asset_handle_get_local_id(const AssetHandle *asset)
ID *ED_asset_handle_get_local_id(const AssetHandle *asset_handle)
{
return asset->file_data->id;
return AS_asset_representation_local_id_get(asset_handle->file_data->asset);
}
ID_Type ED_asset_handle_get_id_type(const AssetHandle *asset)
ID_Type ED_asset_handle_get_id_type(const AssetHandle *asset_handle)
{
return static_cast<ID_Type>(asset->file_data->blentype);
return AS_asset_representation_id_type_get(asset_handle->file_data->asset);
}
int ED_asset_handle_get_preview_icon_id(const AssetHandle *asset)
@ -51,17 +51,6 @@ int ED_asset_handle_get_preview_icon_id(const AssetHandle *asset)
return asset->file_data->preview_icon_id;
}
std::optional<eAssetImportMethod> ED_asset_handle_get_import_method(
const AssetHandle *asset_handle)
{
return AS_asset_representation_import_method_get(asset_handle->file_data->asset);
}
blender::StringRefNull ED_asset_handle_get_library_relative_identifier(const AssetHandle &asset)
{
return AS_asset_representation_library_relative_identifier_get(asset.file_data->asset);
}
void ED_asset_handle_get_full_library_path(const AssetHandle *asset_handle,
char r_full_lib_path[FILE_MAX])
{
@ -75,8 +64,3 @@ void ED_asset_handle_get_full_library_path(const AssetHandle *asset_handle,
BLI_strncpy(r_full_lib_path, library_path.c_str(), FILE_MAX);
}
bool ED_asset_handle_get_use_relative_path(const AssetHandle *asset)
{
return AS_asset_representation_use_relative_path_get(asset->file_data->asset);
}

View File

@ -6,24 +6,19 @@
* \ingroup edasset
*/
#include "AS_asset_representation.h"
#include "AS_asset_representation.hh"
#include "BLO_readfile.h"
#include "WM_api.h"
#include "ED_asset_import.h"
#include "ED_asset_import.hh"
using namespace blender;
ID *ED_asset_get_local_id_from_asset_or_append_and_reuse(Main *bmain,
const AssetRepresentation *asset_c_ptr,
ID_Type idtype)
ID *ED_asset_get_local_id_from_asset_or_append_and_reuse(
Main *bmain, const asset_system::AssetRepresentation &asset, ID_Type idtype)
{
const asset_system::AssetRepresentation &asset =
*reinterpret_cast<const asset_system::AssetRepresentation *>(asset_c_ptr);
if (ID *local_id = asset.local_id()) {
return local_id;
}

View File

@ -31,7 +31,6 @@
#include "../space_file/file_indexer.h"
#include "../space_file/filelist.h"
#include "ED_asset_handle.h"
#include "ED_asset_indexer.h"
#include "ED_asset_list.h"
#include "ED_asset_list.hh"
@ -121,6 +120,7 @@ class AssetList : NonCopyable {
bool needsRefetch() const;
bool isLoaded() const;
asset_system::AssetLibrary *asset_library() const;
void iterate(AssetListHandleIterFn fn) const;
void iterate(AssetListIterFn fn) const;
int size() const;
void tagMainDataDirty() const;
@ -196,7 +196,7 @@ asset_system::AssetLibrary *AssetList::asset_library() const
return reinterpret_cast<asset_system::AssetLibrary *>(filelist_asset_library(filelist_));
}
void AssetList::iterate(AssetListIterFn fn) const
void AssetList::iterate(AssetListHandleIterFn fn) const
{
FileList *files = filelist_;
int numfiles = filelist_files_ensure(files);
@ -215,6 +215,16 @@ void AssetList::iterate(AssetListIterFn fn) const
}
}
void AssetList::iterate(AssetListIterFn fn) const
{
iterate([&fn](AssetHandle handle) {
asset_system::AssetRepresentation &asset =
reinterpret_cast<blender::asset_system::AssetRepresentation &>(*handle.file_data->asset);
return fn(asset);
});
}
void AssetList::ensurePreviewsJob(const bContext *C)
{
FileList *files = filelist_;
@ -465,6 +475,14 @@ bool ED_assetlist_storage_has_list_for_library(const AssetLibraryReference *libr
return AssetListStorage::lookup_list(*library_reference) != nullptr;
}
void ED_assetlist_iterate(const AssetLibraryReference &library_reference, AssetListHandleIterFn fn)
{
AssetList *list = AssetListStorage::lookup_list(library_reference);
if (list) {
list->iterate(fn);
}
}
void ED_assetlist_iterate(const AssetLibraryReference &library_reference, AssetListIterFn fn)
{
AssetList *list = AssetListStorage::lookup_list(library_reference);
@ -483,13 +501,21 @@ asset_system::AssetLibrary *ED_assetlist_library_get_once_available(
return list->asset_library();
}
AssetHandle ED_assetlist_asset_get_by_index(const AssetLibraryReference *library_reference,
int asset_index)
AssetHandle ED_assetlist_asset_handle_get_by_index(const AssetLibraryReference *library_reference,
int asset_index)
{
const AssetList *list = AssetListStorage::lookup_list(*library_reference);
return list->asset_get_by_index(asset_index);
}
asset_system::AssetRepresentation *ED_assetlist_asset_get_by_index(
const AssetLibraryReference &library_reference, int asset_index)
{
AssetHandle asset_handle = ED_assetlist_asset_handle_get_by_index(&library_reference,
asset_index);
return reinterpret_cast<asset_system::AssetRepresentation *>(asset_handle.file_data->asset);
}
ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle)
{
ImBuf *imbuf = filelist_file_getimage(asset_handle->file_data);

View File

@ -16,6 +16,8 @@
#include "BLI_utildefines.h"
#include "BLI_vector_set.hh"
#include "BLT_translation.h"
#include "ED_curves.h"
#include "ED_object.h"
#include "ED_screen.h"
@ -938,15 +940,15 @@ static void CURVES_OT_select_random(wmOperatorType *ot)
1.0f);
}
static int select_end_exec(bContext *C, wmOperator *op)
static int select_ends_exec(bContext *C, wmOperator *op)
{
VectorSet<Curves *> unique_curves = curves::get_unique_editable_curves(*C);
const bool end_points = RNA_boolean_get(op->ptr, "end_points");
const int amount = RNA_int_get(op->ptr, "amount");
const int amount_start = RNA_int_get(op->ptr, "amount_start");
const int amount_end = RNA_int_get(op->ptr, "amount_end");
for (Curves *curves_id : unique_curves) {
CurvesGeometry &curves = curves_id->geometry.wrap();
select_ends(curves, amount, end_points);
select_ends(curves, amount_start, amount_end);
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
* attribute for now. */
@ -957,24 +959,48 @@ static int select_end_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static void CURVES_OT_select_end(wmOperatorType *ot)
static void select_ends_ui(bContext * /*C*/, wmOperator *op)
{
ot->name = "Select End";
uiLayout *layout = op->layout;
uiLayoutSetPropSep(layout, true);
uiLayout *col = uiLayoutColumn(layout, true);
uiLayoutSetPropDecorate(col, false);
uiItemR(col, op->ptr, "amount_start", 0, IFACE_("Amount Start"), ICON_NONE);
uiItemR(col, op->ptr, "amount_end", 0, IFACE_("End"), ICON_NONE);
}
static void CURVES_OT_select_ends(wmOperatorType *ot)
{
ot->name = "Select Ends";
ot->idname = __func__;
ot->description = "Select end points of curves";
ot->exec = select_end_exec;
ot->exec = select_ends_exec;
ot->ui = select_ends_ui;
ot->poll = editable_curves_point_domain_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna,
"end_points",
true,
"End Points",
"Select points at the end of the curve as opposed to the beginning");
RNA_def_int(
ot->srna, "amount", 1, 0, INT32_MAX, "Amount", "Number of points to select", 0, INT32_MAX);
RNA_def_int(ot->srna,
"amount_start",
0,
0,
INT32_MAX,
"Amount Front",
"Number of points to select from the front",
0,
INT32_MAX);
RNA_def_int(ot->srna,
"amount_end",
1,
0,
INT32_MAX,
"Amount Back",
"Number of points to select from the back",
0,
INT32_MAX);
}
static int select_linked_exec(bContext *C, wmOperator * /*op*/)
@ -1181,7 +1207,7 @@ void ED_operatortypes_curves()
WM_operatortype_append(CURVES_OT_set_selection_domain);
WM_operatortype_append(CURVES_OT_select_all);
WM_operatortype_append(CURVES_OT_select_random);
WM_operatortype_append(CURVES_OT_select_end);
WM_operatortype_append(CURVES_OT_select_ends);
WM_operatortype_append(CURVES_OT_select_linked);
WM_operatortype_append(CURVES_OT_select_more);
WM_operatortype_append(CURVES_OT_select_less);

View File

@ -222,7 +222,7 @@ void select_all(bke::CurvesGeometry &curves, const eAttrDomain selection_domain,
}
}
void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points)
void select_ends(bke::CurvesGeometry &curves, int amount_start, int amount_end)
{
const bool was_anything_selected = has_anything_selected(curves);
const OffsetIndices points_by_curve = curves.points_by_curve();
@ -240,12 +240,9 @@ void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points)
MutableSpan<T> selection_typed = selection.span.typed<T>();
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
for (const int curve_i : range) {
if (end_points) {
selection_typed.slice(points_by_curve[curve_i].drop_back(amount)).fill(T(0));
}
else {
selection_typed.slice(points_by_curve[curve_i].drop_front(amount)).fill(T(0));
}
selection_typed
.slice(points_by_curve[curve_i].drop_front(amount_start).drop_back(amount_end))
.fill(T(0));
}
});
}

View File

@ -99,28 +99,3 @@ void ED_gizmo_draw_preset_circle(const struct wmGizmo *gz,
single_axis_convert(OB_POSZ, mat, axis, mat_rotate);
ed_gizmo_draw_preset_geometry(gz, mat_rotate, select_id, &wm_gizmo_geom_data_dial);
}
void ED_gizmo_draw_preset_facemap(
const bContext *C, const struct wmGizmo *gz, Object *ob, const int facemap, int select_id)
{
/* Dependency graph is supposed to be evaluated prior to draw. */
Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
const bool is_select = (select_id != -1);
const bool is_highlight = is_select && (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
float color[4];
gizmo_color_get(gz, is_highlight, color);
if (is_select) {
GPU_select_load_id(select_id);
}
GPU_matrix_push();
GPU_matrix_mul(ob->object_to_world);
ED_draw_object_facemap(depsgraph, ob, color, facemap);
GPU_matrix_pop();
if (is_select) {
GPU_select_load_id(-1);
}
}

View File

@ -25,9 +25,7 @@ void ED_operatortypes_asset(void);
#endif
#include "../asset/ED_asset_catalog.h"
#include "../asset/ED_asset_filter.h"
#include "../asset/ED_asset_handle.h"
#include "../asset/ED_asset_import.h"
#include "../asset/ED_asset_library.h"
#include "../asset/ED_asset_list.h"
#include "../asset/ED_asset_mark_clear.h"
@ -37,5 +35,7 @@ void ED_operatortypes_asset(void);
/* C++ only headers. */
#ifdef __cplusplus
# include "../asset/ED_asset_catalog.hh"
# include "../asset/ED_asset_filter.hh"
# include "../asset/ED_asset_import.hh"
# include "../asset/ED_asset_list.hh"
#endif

View File

@ -150,10 +150,10 @@ void select_all(bke::CurvesGeometry &curves, eAttrDomain selection_domain, int a
/**
* Select the ends (front or back) of all the curves.
*
* \param amount: The amount of points to select from the front or back.
* \param end_points: If true, select the last point(s), if false, select the first point(s).
* \param amount_start: The amount of points to select from the front.
* \param amount_end: The amount of points to select from the back.
*/
void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points);
void select_ends(bke::CurvesGeometry &curves, int amount_start, int amount_end);
/**
* Select the points of all curves that have at least one point selected.

View File

@ -52,11 +52,6 @@ void ED_gizmo_draw_preset_circle(const struct wmGizmo *gz,
float mat[4][4],
int axis,
int select_id);
void ED_gizmo_draw_preset_facemap(const struct bContext *C,
const struct wmGizmo *gz,
struct Object *ob,
int facemap,
int select_id);
/* -------------------------------------------------------------------- */
/* 3D Arrow Gizmo */

View File

@ -34,7 +34,6 @@ struct ViewLayer;
struct XFormObjectData;
struct bConstraint;
struct bContext;
struct bFaceMap;
struct bPoseChannel;
struct uiLayout;
struct wmKeyConfig;
@ -729,17 +728,6 @@ bool ED_object_jump_to_bone(struct bContext *C,
const char *bone_name,
bool reveal_hidden);
/* object_facemap_ops.c */
/**
* Called while not in edit-mode.
*/
void ED_object_facemap_face_add(struct Object *ob, struct bFaceMap *fmap, int facenum);
/**
* Called while not in edit-mode.
*/
void ED_object_facemap_face_remove(struct Object *ob, struct bFaceMap *fmap, int facenum);
/* object_data_transform.cc */
struct XFormObjectData *ED_object_data_xform_create_ex(struct ID *id, bool is_edit_mode);

View File

@ -1056,10 +1056,6 @@ void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d);
struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d);
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat);
void ED_draw_object_facemap(struct Depsgraph *depsgraph,
struct Object *ob,
const float col[4],
int facemap);
struct RenderEngineType *ED_view3d_engine_type(const struct Scene *scene, int drawtype);

View File

@ -22,7 +22,7 @@ extern "C" {
struct ARegion;
struct AssetFilterSettings;
struct AssetHandle;
struct AssetRepresentation;
struct AutoComplete;
struct EnumPropertyItem;
struct FileSelectParams;
@ -1813,8 +1813,7 @@ void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, float scale);
* \param asset: May be passed from a temporary variable, drag data only stores a copy of this.
*/
void UI_but_drag_set_asset(uiBut *but,
const struct AssetHandle *asset,
const char *path,
const struct AssetRepresentation *asset,
int import_type, /* eAssetImportType */
int icon,
struct ImBuf *imb,

View File

@ -30,15 +30,13 @@ void UI_but_drag_attach_image(uiBut *but, ImBuf *imb, const float scale)
}
void UI_but_drag_set_asset(uiBut *but,
const AssetHandle *asset_handle,
const char *path,
const AssetRepresentation *asset,
int import_type,
int icon,
ImBuf *imb,
float scale)
{
wmDragAsset *asset_drag = WM_drag_create_asset_data(
asset_handle, path, import_type, static_cast<bContext *>(but->block->evil_C));
wmDragAsset *asset_drag = WM_drag_create_asset_data(asset, import_type, static_cast<bContext *>(but->block->evil_C));
but->dragtype = WM_DRAG_ASSET;
ui_def_but_icon(but, icon, 0); /* no flag UI_HAS_ICON, so icon doesn't draw in button */

View File

@ -6,6 +6,9 @@
* \ingroup edinterface
*/
#include "AS_asset_representation.h"
#include "AS_asset_representation.hh"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
@ -33,6 +36,8 @@
#include "interface_intern.hh"
using namespace blender;
struct AssetViewListData {
AssetLibraryReference asset_library_ref;
AssetFilterSettings filter_settings;
@ -42,28 +47,20 @@ struct AssetViewListData {
static void asset_view_item_but_drag_set(uiBut *but, AssetHandle *asset_handle)
{
ID *id = ED_asset_handle_get_local_id(asset_handle);
AssetRepresentation *asset = ED_asset_handle_get_representation(asset_handle);
ID *id = AS_asset_representation_local_id_get(asset);
if (id != nullptr) {
UI_but_drag_set_id(but, id);
return;
}
char blend_path[FILE_MAX_LIBEXTRA];
ED_asset_handle_get_full_library_path(asset_handle, blend_path);
const eAssetImportMethod import_method =
ED_asset_handle_get_import_method(asset_handle).value_or(ASSET_IMPORT_APPEND_REUSE);
AS_asset_representation_import_method_get(asset).value_or(ASSET_IMPORT_APPEND_REUSE);
if (blend_path[0]) {
ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle);
UI_but_drag_set_asset(but,
asset_handle,
BLI_strdup(blend_path),
import_method,
ED_asset_handle_get_preview_icon_id(asset_handle),
imbuf,
1.0f);
}
ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle);
UI_but_drag_set_asset(
but, asset, import_method, ED_asset_handle_get_preview_icon_id(asset_handle), imbuf, 1.0f);
}
static void asset_view_draw_item(uiList *ui_list,
@ -79,7 +76,8 @@ static void asset_view_draw_item(uiList *ui_list,
{
AssetViewListData *list_data = (AssetViewListData *)ui_list->dyn_data->customdata;
AssetHandle asset_handle = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
AssetHandle asset_handle = ED_assetlist_asset_handle_get_by_index(&list_data->asset_library_ref,
index);
PointerRNA file_ptr;
RNA_pointer_create(&list_data->screen->id,
@ -132,8 +130,10 @@ static void asset_view_filter_items(uiList *ui_list,
C,
[&name_filter, list_data, &filter_settings](
const PointerRNA &itemptr, blender::StringRefNull name, int index) {
AssetHandle asset = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
asset_system::AssetRepresentation *asset = ED_assetlist_asset_get_by_index(
list_data->asset_library_ref, index);
if (!ED_asset_filter_matches_asset(&filter_settings, *asset)) {
return UI_LIST_ITEM_NEVER_SHOW;
}
return name_filter(itemptr, name, index);
@ -141,8 +141,10 @@ static void asset_view_filter_items(uiList *ui_list,
dataptr,
propname,
[list_data](const PointerRNA & /*itemptr*/, int index) -> std::string {
AssetHandle asset = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
return ED_asset_handle_get_name(&asset);
asset_system::AssetRepresentation *asset = ED_assetlist_asset_get_by_index(
list_data->asset_library_ref, index);
return asset->get_name();
});
}

View File

@ -976,6 +976,9 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
id->us = 0;
undo_push_label = "Delete Data-Block";
}
else {
undo_push_label = "Unlink Data-Block";
}
break;
case UI_ID_FAKE_USER:

View File

@ -2221,23 +2221,6 @@ bool EDBM_select_pick(bContext *C, const int mval[2], const SelectPick_Params *p
vc.em->mat_nr = efa->mat_nr;
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, nullptr);
}
/* Change active face-map on object. */
if (!BLI_listbase_is_empty(&vc.obedit->fmaps)) {
const int cd_fmap_offset = CustomData_get_offset(&vc.em->bm->pdata, CD_FACEMAP);
if (cd_fmap_offset != -1) {
int map = *((int *)BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset));
if ((map < -1) || (map > BLI_listbase_count_at_most(&vc.obedit->fmaps, map))) {
map = -1;
}
map += 1;
if (map != vc.obedit->actfmap) {
/* We may want to add notifiers later,
* currently select update handles redraw. */
vc.obedit->actfmap = map;
}
}
}
}
/* Changing active object is handy since it allows us to

View File

@ -76,7 +76,6 @@ static const EnumPropertyItem prop_similar_types[] = {
{SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
{SIMFACE_COPLANAR, "COPLANAR", 0, "Coplanar", ""},
{SIMFACE_SMOOTH, "SMOOTH", 0, "Flat/Smooth", ""},
{SIMFACE_FACEMAP, "FACE_MAP", 0, "Face Map", ""},
#ifdef WITH_FREESTYLE
{SIMFACE_FREESTYLE, "FREESTYLE_FACE", 0, "Freestyle Face Marks", ""},
#endif
@ -177,7 +176,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
KDTree_3d *tree_3d = NULL;
KDTree_4d *tree_4d = NULL;
GSet *gset = NULL;
GSet **gset_array = NULL;
int face_data_value = SIMFACE_DATA_NONE;
switch (type) {
@ -195,10 +193,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
case SIMFACE_MATERIAL:
gset = BLI_gset_ptr_new("Select similar face");
break;
case SIMFACE_FACEMAP:
gset_array = MEM_callocN(sizeof(GSet *) * objects_len,
"Select similar face: facemap gset array");
break;
}
int tree_index = 0;
@ -208,7 +202,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
BMesh *bm = em->bm;
Material ***material_array = NULL;
invert_m4_m4(ob->world_to_object, ob->object_to_world);
int custom_data_offset = 0;
if (bm->totfacesel == 0) {
continue;
@ -232,13 +225,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
}
break;
}
case SIMFACE_FACEMAP: {
custom_data_offset = CustomData_get_offset(&bm->pdata, CD_FACEMAP);
if (custom_data_offset == -1) {
continue;
}
gset_array[ob_index] = BLI_gset_ptr_new("Select similar face: facemap gset");
}
}
BMFace *face; /* Mesh face. */
@ -301,12 +287,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
}
break;
}
case SIMFACE_FACEMAP: {
BLI_assert(custom_data_offset != -1);
int *face_map = BM_ELEM_CD_GET_VOID_P(face, custom_data_offset);
BLI_gset_add(gset_array[ob_index], face_map);
break;
}
}
}
}
@ -333,7 +313,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
BMesh *bm = em->bm;
bool changed = false;
Material ***material_array = NULL;
int custom_data_offset;
float ob_m3[3][3];
copy_m3_m4(ob_m3, ob->object_to_world);
@ -354,12 +333,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
}
break;
}
case SIMFACE_FACEMAP: {
custom_data_offset = CustomData_get_offset(&bm->pdata, CD_FACEMAP);
if (custom_data_offset == -1) {
continue;
}
}
}
BMFace *face; /* Mesh face. */
@ -467,18 +440,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
}
break;
}
case SIMFACE_FACEMAP: {
const int *face_map = BM_ELEM_CD_GET_VOID_P(face, custom_data_offset);
GSetIterator gs_iter;
GSET_ITER (gs_iter, gset_array[ob_index]) {
const int *face_map_iter = BLI_gsetIterator_getKey(&gs_iter);
if (*face_map == *face_map_iter) {
select = true;
break;
}
}
break;
}
}
if (select) {
@ -533,14 +494,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
if (gset != NULL) {
BLI_gset_free(gset, NULL);
}
if (gset_array != NULL) {
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
if (gset_array[ob_index] != NULL) {
BLI_gset_free(gset_array[ob_index], NULL);
}
}
MEM_freeN(gset_array);
}
return OPERATOR_FINISHED;
}
@ -1376,7 +1329,7 @@ static const EnumPropertyItem *select_similar_type_itemf(bContext *C,
#ifdef WITH_FREESTYLE
const int a_end = SIMFACE_FREESTYLE;
#else
const int a_end = SIMFACE_FACEMAP;
const int a_end = SIMFACE_MATERIAL;
#endif
for (a = SIMFACE_MATERIAL; a <= a_end; a++) {
RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a);

View File

@ -40,7 +40,6 @@
#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
#include "BKE_object_facemap.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h"
@ -273,23 +272,6 @@ static void join_mesh_single(Depsgraph *depsgraph,
for (const int i : blender::IndexRange(me->totpoly)) {
poly_offsets[i] = src_poly_offsets[i] + *loopofs;
}
/* Face maps. */
int *fmap = (int *)CustomData_get_for_write(pdata, *polyofs, CD_FACEMAP, totpoly);
const int *fmap_src = (const int *)CustomData_get_for_write(
&me->pdata, 0, CD_FACEMAP, me->totpoly);
/* Remap to correct new face-map indices, if needed. */
if (fmap_src) {
BLI_assert(fmap != nullptr);
int *fmap_index_map;
int fmap_index_map_len;
fmap_index_map = BKE_object_facemap_index_map_create(ob_src, ob_dst, &fmap_index_map_len);
BKE_object_facemap_index_map_apply(fmap, me->totpoly, fmap_index_map, fmap_index_map_len);
if (fmap_index_map != nullptr) {
MEM_freeN(fmap_index_map);
}
}
}
/* these are used for relinking (cannot be set earlier, or else reattaching goes wrong) */
@ -483,19 +465,6 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
me->vertex_group_active_index = 1;
}
/* Join this object's face maps to the base one's. */
LISTBASE_FOREACH (bFaceMap *, fmap, &ob_iter->fmaps) {
/* See if this group exists in the object (if it doesn't, add it to the end) */
if (BKE_object_facemap_find_name(ob, fmap->name) == nullptr) {
bFaceMap *fmap_new = static_cast<bFaceMap *>(MEM_mallocN(sizeof(bFaceMap), __func__));
memcpy(fmap_new, fmap, sizeof(bFaceMap));
BLI_addtail(&ob->fmaps, fmap_new);
}
}
if (ob->fmaps.first && ob->actfmap == 0) {
ob->actfmap = 1;
}
mesh_join_offset_face_sets_ID(me, &face_set_id_offset);
if (me->totvert) {

View File

@ -44,7 +44,6 @@ set(SRC
object_data_transfer.c
object_data_transform.cc
object_edit.cc
object_facemap_ops.c
object_gpencil_modifier.c
object_hook.c
object_light_linking_ops.cc

View File

@ -1,493 +0,0 @@
/* SPDX-FileCopyrightText: 2008 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup edobj
*/
#include <string.h>
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_workspace_types.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
#include "BKE_object_facemap.h"
#include "DEG_depsgraph.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
#include "ED_object.h"
#include "object_intern.h"
void ED_object_facemap_face_add(Object *ob, bFaceMap *fmap, int facenum)
{
int fmap_nr;
if (GS(((ID *)ob->data)->name) != ID_ME) {
return;
}
/* get the face map number, exit if it can't be found */
fmap_nr = BLI_findindex(&ob->fmaps, fmap);
if (fmap_nr != -1) {
int *facemap;
Mesh *me = ob->data;
/* if there's is no facemap layer then create one */
if ((facemap = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly)) == NULL) {
facemap = CustomData_add_layer(&me->pdata, CD_FACEMAP, CD_SET_DEFAULT, me->totpoly);
}
facemap[facenum] = fmap_nr;
}
}
void ED_object_facemap_face_remove(Object *ob, bFaceMap *fmap, int facenum)
{
int fmap_nr;
if (GS(((ID *)ob->data)->name) != ID_ME) {
return;
}
/* get the face map number, exit if it can't be found */
fmap_nr = BLI_findindex(&ob->fmaps, fmap);
if (fmap_nr != -1) {
int *facemap;
Mesh *me = ob->data;
if ((facemap = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly)) == NULL) {
return;
}
facemap[facenum] = -1;
}
}
static void object_fmap_remap_edit_mode(Object *ob, const int *remap)
{
if (ob->type != OB_MESH) {
return;
}
Mesh *me = ob->data;
if (me->edit_mesh) {
BMEditMesh *em = me->edit_mesh;
const int cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
if (cd_fmap_offset != -1) {
BMFace *efa;
BMIter iter;
int *map;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (map && *map != -1) {
*map = remap[*map];
}
}
}
}
}
static void object_fmap_remap_object_mode(Object *ob, const int *remap)
{
if (ob->type != OB_MESH) {
return;
}
Mesh *me = ob->data;
if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
int *map = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly);
if (map) {
for (int i = 0; i < me->totpoly; i++) {
if (map[i] != -1) {
map[i] = remap[map[i]];
}
}
}
}
}
static void object_facemap_remap(Object *ob, const int *remap)
{
if (BKE_object_is_in_editmode(ob)) {
object_fmap_remap_edit_mode(ob, remap);
}
else {
object_fmap_remap_object_mode(ob, remap);
}
}
static bool face_map_supported_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
return (ob && !ID_IS_LINKED(ob) && !ID_IS_OVERRIDE_LIBRARY(ob) && ob->type == OB_MESH && data &&
!ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data));
}
static bool face_map_supported_edit_mode_poll(bContext *C)
{
Object *ob = ED_object_context(C);
if (face_map_supported_poll(C)) {
if (ob->mode == OB_MODE_EDIT) {
return true;
}
}
return false;
}
static bool face_map_supported_remove_poll(bContext *C)
{
if (!face_map_supported_poll(C)) {
return false;
}
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
return true;
}
return false;
}
static int face_map_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
BKE_object_facemap_add(ob);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_add(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add Face Map";
ot->idname = "OBJECT_OT_face_map_add";
ot->description = "Add a new face map to the active object";
/* api callbacks */
ot->poll = face_map_supported_poll;
ot->exec = face_map_add_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int face_map_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
BKE_object_facemap_remove(ob, fmap);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_remove(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove Face Map";
ot->idname = "OBJECT_OT_face_map_remove";
ot->description = "Remove a face map from the active object";
/* api callbacks */
ot->poll = face_map_supported_remove_poll;
ot->exec = face_map_remove_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int face_map_assign_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
Mesh *me = ob->data;
BMEditMesh *em = me->edit_mesh;
BMFace *efa;
BMIter iter;
int *map;
int cd_fmap_offset;
if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP)) {
BM_data_layer_add(em->bm, &em->bm->pdata, CD_FACEMAP);
}
cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
*map = ob->actfmap - 1;
}
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_assign(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Assign Face Map";
ot->idname = "OBJECT_OT_face_map_assign";
ot->description = "Assign faces to a face map";
/* api callbacks */
ot->poll = face_map_supported_edit_mode_poll;
ot->exec = face_map_assign_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int face_map_remove_from_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
Mesh *me = ob->data;
BMEditMesh *em = me->edit_mesh;
BMFace *efa;
BMIter iter;
int *map;
int cd_fmap_offset;
int mapindex = ob->actfmap - 1;
if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP)) {
return OPERATOR_CANCELLED;
}
cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && *map == mapindex) {
*map = -1;
}
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_remove_from(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove from Face Map";
ot->idname = "OBJECT_OT_face_map_remove_from";
ot->description = "Remove faces from a face map";
/* api callbacks */
ot->poll = face_map_supported_edit_mode_poll;
ot->exec = face_map_remove_from_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static void fmap_select(Object *ob, bool select)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_mesh;
BMFace *efa;
BMIter iter;
int *map;
int cd_fmap_offset;
int mapindex = ob->actfmap - 1;
if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP)) {
BM_data_layer_add(em->bm, &em->bm->pdata, CD_FACEMAP);
}
cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (*map == mapindex) {
BM_face_select_set(em->bm, efa, select);
}
}
}
static int face_map_select_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
fmap_select(ob, true);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_select(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select Face Map Faces";
ot->idname = "OBJECT_OT_face_map_select";
ot->description = "Select faces belonging to a face map";
/* api callbacks */
ot->poll = face_map_supported_edit_mode_poll;
ot->exec = face_map_select_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int face_map_deselect_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
fmap_select(ob, false);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_deselect(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Deselect Face Map Faces";
ot->idname = "OBJECT_OT_face_map_deselect";
ot->description = "Deselect faces belonging to a face map";
/* api callbacks */
ot->poll = face_map_supported_edit_mode_poll;
ot->exec = face_map_deselect_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int face_map_move_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
bFaceMap *fmap;
int dir = RNA_enum_get(op->ptr, "direction");
fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (!fmap) {
return OPERATOR_CANCELLED;
}
if (!fmap->prev && !fmap->next) {
return OPERATOR_CANCELLED;
}
int pos1 = BLI_findindex(&ob->fmaps, fmap);
int pos2 = pos1 - dir;
int len = BLI_listbase_count(&ob->fmaps);
int *map = MEM_mallocN(len * sizeof(*map), __func__);
if (!IN_RANGE(pos2, -1, len)) {
const int offset = len - dir;
for (int i = 0; i < len; i++) {
map[i] = (i + offset) % len;
}
pos2 = map[pos1];
}
else {
range_vn_i(map, len, 0);
SWAP(int, map[pos1], map[pos2]);
}
void *prev = fmap->prev;
void *next = fmap->next;
BLI_remlink(&ob->fmaps, fmap);
if (dir == 1) { /*up*/
BLI_insertlinkbefore(&ob->fmaps, prev, fmap);
}
else { /*down*/
BLI_insertlinkafter(&ob->fmaps, next, fmap);
}
/* Iterate through mesh and substitute the indices as necessary. */
object_facemap_remap(ob, map);
MEM_freeN(map);
ob->actfmap = pos2 + 1;
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_move(wmOperatorType *ot)
{
static EnumPropertyItem fmap_slot_move[] = {
{1, "UP", 0, "Up", ""},
{-1, "DOWN", 0, "Down", ""},
{0, NULL, 0, NULL, NULL},
};
/* identifiers */
ot->name = "Move Face Map";
ot->idname = "OBJECT_OT_face_map_move";
ot->description = "Move the active face map up/down in the list";
/* api callbacks */
ot->poll = face_map_supported_poll;
ot->exec = face_map_move_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_enum(
ot->srna, "direction", fmap_slot_move, 0, "Direction", "Direction to move, up or down");
}

View File

@ -316,16 +316,6 @@ void OBJECT_OT_vertex_weight_set_active(struct wmOperatorType *ot);
void OBJECT_OT_vertex_weight_normalize_active_vertex(struct wmOperatorType *ot);
void OBJECT_OT_vertex_weight_copy(struct wmOperatorType *ot);
/* object_facemap_ops.c */
void OBJECT_OT_face_map_add(struct wmOperatorType *ot);
void OBJECT_OT_face_map_remove(struct wmOperatorType *ot);
void OBJECT_OT_face_map_assign(struct wmOperatorType *ot);
void OBJECT_OT_face_map_remove_from(struct wmOperatorType *ot);
void OBJECT_OT_face_map_select(struct wmOperatorType *ot);
void OBJECT_OT_face_map_deselect(struct wmOperatorType *ot);
void OBJECT_OT_face_map_move(struct wmOperatorType *ot);
/* object_warp.c */
void TRANSFORM_OT_vertex_warp(struct wmOperatorType *ot);

View File

@ -226,13 +226,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_weight_normalize_active_vertex);
WM_operatortype_append(OBJECT_OT_vertex_weight_copy);
WM_operatortype_append(OBJECT_OT_face_map_add);
WM_operatortype_append(OBJECT_OT_face_map_remove);
WM_operatortype_append(OBJECT_OT_face_map_assign);
WM_operatortype_append(OBJECT_OT_face_map_remove_from);
WM_operatortype_append(OBJECT_OT_face_map_select);
WM_operatortype_append(OBJECT_OT_face_map_deselect);
WM_operatortype_append(OBJECT_OT_face_map_move);
WM_operatortype_append(TRANSFORM_OT_vertex_warp);

View File

@ -464,7 +464,6 @@ enum eSculptFaceSetsInitMode {
SCULPT_FACE_SETS_FROM_CREASES = 4,
SCULPT_FACE_SETS_FROM_SHARP_EDGES = 5,
SCULPT_FACE_SETS_FROM_BEVEL_WEIGHT = 6,
SCULPT_FACE_SETS_FROM_FACE_MAPS = 7,
SCULPT_FACE_SETS_FROM_FACE_SET_BOUNDARIES = 8,
};
@ -518,13 +517,7 @@ static EnumPropertyItem prop_sculpt_face_sets_init_types[] = {
"Face Sets from Sharp Edges",
"Create Face Sets using Sharp Edges as boundaries",
},
{
SCULPT_FACE_SETS_FROM_FACE_MAPS,
"FACE_MAPS",
0,
"Face Sets from Face Maps",
"Create a Face Set per Face Map",
},
{
SCULPT_FACE_SETS_FROM_FACE_SET_BOUNDARIES,
"FACE_SET_BOUNDARIES",
@ -610,13 +603,6 @@ static void sculpt_face_sets_init_loop(Object *ob, const int mode)
ss->face_sets[i] = material_indices[i] + 1;
}
}
else if (mode == SCULPT_FACE_SETS_FROM_FACE_MAPS) {
const int *face_maps = static_cast<const int *>(
CustomData_get_layer(&mesh->pdata, CD_FACEMAP));
for (const int i : IndexRange(mesh->totpoly)) {
ss->face_sets[i] = face_maps ? face_maps[i] : 1;
}
}
}
static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
@ -719,10 +705,6 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
});
break;
}
case SCULPT_FACE_SETS_FROM_FACE_MAPS: {
sculpt_face_sets_init_loop(ob, SCULPT_FACE_SETS_FROM_FACE_MAPS);
break;
}
}
SCULPT_undo_push_end(ob);

View File

@ -127,7 +127,7 @@ static SpaceLink *action_create(const ScrArea *area, const Scene *scene)
return (SpaceLink *)saction;
}
/* not spacelink itself */
/* Doesn't free the space-link itself. */
static void action_free(SpaceLink * /*sl*/)
{
// SpaceAction *saction = (SpaceAction *) sl;

View File

@ -303,7 +303,7 @@ static SpaceLink *xxx_create(const ScrArea *UNUSED(area), const Scene *UNUSED(sc
return NULL;
}
/* not spacelink itself */
/* Doesn't free the space-link itself. */
static void xxx_free(SpaceLink *UNUSED(sl)) {}
/* spacetype; init callback for usage, should be re-doable. */

View File

@ -87,7 +87,7 @@ static SpaceLink *buttons_create(const ScrArea *UNUSED(area), const Scene *UNUSE
return (SpaceLink *)sbuts;
}
/* not spacelink itself */
/* Doesn't free the space-link itself. */
static void buttons_free(SpaceLink *sl)
{
SpaceProperties *sbuts = (SpaceProperties *)sl;

View File

@ -200,7 +200,7 @@ static SpaceLink *clip_create(const ScrArea * /*area*/, const Scene * /*scene*/)
return (SpaceLink *)sc;
}
/* not spacelink itself */
/* Doesn't free the space-link itself. */
static void clip_free(SpaceLink *sl)
{
SpaceClip *sc = (SpaceClip *)sl;

View File

@ -22,11 +22,11 @@ set(INC_SYS
)
set(SRC
console_draw.c
console_ops.c
space_console.c
console_draw.cc
console_ops.cc
space_console.cc
console_intern.h
console_intern.hh
)
set(LIB

View File

@ -6,7 +6,7 @@
* \ingroup spconsole
*/
#include <string.h>
#include <cstring>
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@ -22,18 +22,18 @@
#include "UI_resources.h"
#include "UI_view2d.h"
#include "console_intern.h"
#include "console_intern.hh"
#include "../space_info/textview.h"
#include "../space_info/textview.hh"
static enum eTextViewContext_LineFlag console_line_data(TextViewContext *tvc,
uchar fg[4],
uchar UNUSED(bg[4]),
int *UNUSED(icon),
uchar UNUSED(icon_fg[4]),
uchar UNUSED(icon_bg[4]))
uchar /*bg*/[4],
int * /*icon*/,
uchar /*icon_fg*/[4],
uchar /*icon_bg*/[4])
{
const ConsoleLine *cl_iter = tvc->iter;
const ConsoleLine *cl_iter = static_cast<const ConsoleLine *>(tvc->iter);
int fg_id = TH_TEXT;
switch (cl_iter->type) {
@ -58,13 +58,13 @@ static enum eTextViewContext_LineFlag console_line_data(TextViewContext *tvc,
void console_scrollback_prompt_begin(SpaceConsole *sc, ConsoleLine *cl_dummy)
{
/* fake the edit line being in the scroll buffer */
ConsoleLine *cl = sc->history.last;
ConsoleLine *cl = static_cast<ConsoleLine *>(sc->history.last);
int prompt_len = strlen(sc->prompt);
cl_dummy->type = CONSOLE_LINE_INPUT;
cl_dummy->len = prompt_len + cl->len;
cl_dummy->len_alloc = cl_dummy->len + 1;
cl_dummy->line = MEM_mallocN(cl_dummy->len_alloc, "cl_dummy");
cl_dummy->line = static_cast<char *>(MEM_mallocN(cl_dummy->len_alloc, "cl_dummy"));
memcpy(cl_dummy->line, sc->prompt, prompt_len);
memcpy(cl_dummy->line + prompt_len, cl->line, cl->len + 1);
BLI_addtail(&sc->scrollback, cl_dummy);
@ -85,7 +85,7 @@ static int console_textview_begin(TextViewContext *tvc)
/* iterator */
tvc->iter = sc->scrollback.last;
return (tvc->iter != NULL);
return (tvc->iter != nullptr);
}
static void console_textview_end(TextViewContext *tvc)
@ -96,12 +96,12 @@ static void console_textview_end(TextViewContext *tvc)
static int console_textview_step(TextViewContext *tvc)
{
return ((tvc->iter = (void *)((Link *)tvc->iter)->prev) != NULL);
return ((tvc->iter = (void *)((Link *)tvc->iter)->prev) != nullptr);
}
static void console_textview_line_get(TextViewContext *tvc, const char **r_line, int *r_len)
{
const ConsoleLine *cl = tvc->iter;
const ConsoleLine *cl = static_cast<const ConsoleLine *>(tvc->iter);
*r_line = cl->line;
*r_len = cl->len;
// printf("'%s' %d\n", *line, cl->len);
@ -137,12 +137,12 @@ static void console_textview_draw_cursor(TextViewContext *tvc, int cwidth, int c
const ConsoleLine *cl = (ConsoleLine *)sc->history.last;
int offl = 0, offc = 0;
console_cursor_wrap_offset(sc->prompt, columns, &offl, &offc, NULL);
console_cursor_wrap_offset(sc->prompt, columns, &offl, &offc, nullptr);
console_cursor_wrap_offset(cl->line, columns, &offl, &offc, cl->line + cl->cursor);
pen[0] = cwidth * offc;
pen[1] = -tvc->lheight * offl;
console_cursor_wrap_offset(cl->line + cl->cursor, columns, &offl, &offc, NULL);
console_cursor_wrap_offset(cl->line + cl->cursor, columns, &offl, &offc, nullptr);
pen[1] += tvc->lheight * offl;
pen[0] += tvc->draw_rect.xmin;
@ -160,7 +160,7 @@ static void console_textview_draw_cursor(TextViewContext *tvc, int cwidth, int c
immUnbindProgram();
}
static void console_textview_const_colors(TextViewContext *UNUSED(tvc), uchar bg_sel[4])
static void console_textview_const_colors(TextViewContext * /*tvc*/, uchar bg_sel[4])
{
UI_GetThemeColor4ubv(TH_CONSOLE_SELECT, bg_sel);
}
@ -189,7 +189,7 @@ static int console_textview_main__internal(SpaceConsole *sc,
void **r_mval_pick_item,
int *r_mval_pick_offset)
{
ConsoleLine cl_dummy = {NULL};
ConsoleLine cl_dummy = {nullptr};
int ret = 0;
const View2D *v2d = &region->v2d;
@ -206,7 +206,7 @@ static int console_textview_main__internal(SpaceConsole *sc,
tvc.const_colors = console_textview_const_colors;
tvc.arg1 = sc;
tvc.arg2 = NULL;
tvc.arg2 = nullptr;
/* view */
tvc.sel_start = sc->sel_start;
@ -227,19 +227,19 @@ static int console_textview_main__internal(SpaceConsole *sc,
void console_textview_main(SpaceConsole *sc, const ARegion *region)
{
const int mval[2] = {INT_MAX, INT_MAX};
console_textview_main__internal(sc, region, true, mval, NULL, NULL);
console_textview_main__internal(sc, region, true, mval, nullptr, nullptr);
}
int console_textview_height(SpaceConsole *sc, const ARegion *region)
{
const int mval[2] = {INT_MAX, INT_MAX};
return console_textview_main__internal(sc, region, false, mval, NULL, NULL);
return console_textview_main__internal(sc, region, false, mval, nullptr, nullptr);
}
int console_char_pick(SpaceConsole *sc, const ARegion *region, const int mval[2])
{
int r_mval_pick_offset = 0;
void *mval_pick_item = NULL;
void *mval_pick_item = nullptr;
console_textview_main__internal(sc, region, false, mval, &mval_pick_item, &r_mval_pick_offset);
return r_mval_pick_offset;

View File

@ -6,9 +6,9 @@
* \ingroup spconsole
*/
#include <ctype.h> /* #ispunct */
#include <stdlib.h>
#include <string.h>
#include <cctype> /* #ispunct */
#include <cstdlib>
#include <cstring>
#include <sys/stat.h>
#include "MEM_guardedalloc.h"
@ -35,7 +35,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
#include "console_intern.h"
#include "console_intern.hh"
/* -------------------------------------------------------------------- */
/** \name Utilities
@ -44,23 +44,23 @@
static char *console_select_to_buffer(SpaceConsole *sc)
{
if (sc->sel_start == sc->sel_end) {
return NULL;
return nullptr;
}
ConsoleLine cl_dummy = {NULL};
ConsoleLine cl_dummy = {nullptr};
console_scrollback_prompt_begin(sc, &cl_dummy);
int offset = 0;
for (ConsoleLine *cl = sc->scrollback.first; cl; cl = cl->next) {
for (ConsoleLine *cl = static_cast<ConsoleLine *>(sc->scrollback.first); cl; cl = cl->next) {
offset += cl->len + 1;
}
char *buf_str = NULL;
char *buf_str = nullptr;
if (offset != 0) {
offset -= 1;
int sel[2] = {offset - sc->sel_end, offset - sc->sel_start};
DynStr *buf_dyn = BLI_dynstr_new();
for (ConsoleLine *cl = sc->scrollback.first; cl; cl = cl->next) {
for (ConsoleLine *cl = static_cast<ConsoleLine *>(sc->scrollback.first); cl; cl = cl->next) {
if (sel[0] <= cl->len && sel[1] >= 0) {
int sta = max_ii(sel[0], 0);
int end = min_ii(sel[1], cl->len);
@ -94,7 +94,7 @@ static void console_select_update_primary_clipboard(SpaceConsole *sc)
return;
}
char *buf = console_select_to_buffer(sc);
if (buf == NULL) {
if (buf == nullptr) {
return;
}
WM_clipboard_text_set(buf, true);
@ -108,7 +108,7 @@ static void console_scroll_bottom(ARegion *region)
{
View2D *v2d = &region->v2d;
v2d->cur.ymin = 0.0;
v2d->cur.ymax = (float)v2d->winy;
v2d->cur.ymax = float(v2d->winy);
}
void console_textview_update_rect(SpaceConsole *sc, ARegion *region)
@ -142,7 +142,7 @@ static void console_scrollback_limit(SpaceConsole *sc)
int tot;
for (tot = BLI_listbase_count(&sc->scrollback); tot > U.scrollback; tot--) {
console_scrollback_free(sc, sc->scrollback.first);
console_scrollback_free(sc, static_cast<ConsoleLine *>(sc->scrollback.first));
}
}
@ -150,7 +150,7 @@ static ConsoleLine *console_history_find(SpaceConsole *sc, const char *str, Cons
{
ConsoleLine *cl;
for (cl = sc->history.last; cl; cl = cl->prev) {
for (cl = static_cast<ConsoleLine *>(sc->history.last); cl; cl = cl->prev) {
if (cl == cl_ignore) {
continue;
}
@ -160,7 +160,7 @@ static ConsoleLine *console_history_find(SpaceConsole *sc, const char *str, Cons
}
}
return NULL;
return nullptr;
}
/* return 0 if no change made, clamps the range */
@ -208,7 +208,8 @@ static void console_history_debug(const bContext *C)
static ConsoleLine *console_lb_add__internal(ListBase *lb, ConsoleLine *from)
{
ConsoleLine *ci = MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add");
ConsoleLine *ci = static_cast<ConsoleLine *>(
MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add"));
if (from) {
BLI_assert(strlen(from->line) == from->len);
@ -218,7 +219,7 @@ static ConsoleLine *console_lb_add__internal(ListBase *lb, ConsoleLine *from)
ci->type = from->type;
}
else {
ci->line = MEM_callocN(64, "console-in-line");
ci->line = static_cast<char *>(MEM_callocN(64, "console-in-line"));
ci->len_alloc = 64;
ci->len = 0;
}
@ -243,7 +244,8 @@ static ConsoleLine *console_scrollback_add(const bContext *C, ConsoleLine *from)
static ConsoleLine *console_lb_add_str__internal(ListBase *lb, char *str, bool own)
{
ConsoleLine *ci = MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add");
ConsoleLine *ci = static_cast<ConsoleLine *>(
MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add"));
if (own) {
ci->line = str;
}
@ -270,9 +272,9 @@ ConsoleLine *console_scrollback_add_str(SpaceConsole *sc, char *str, bool own)
ConsoleLine *console_history_verify(const bContext *C)
{
SpaceConsole *sc = CTX_wm_space_console(C);
ConsoleLine *ci = sc->history.last;
if (ci == NULL) {
ci = console_history_add(sc, NULL);
ConsoleLine *ci = static_cast<ConsoleLine *>(sc->history.last);
if (ci == nullptr) {
ci = console_history_add(sc, nullptr);
}
return ci;
@ -288,7 +290,7 @@ static void console_line_verify_length(ConsoleLine *ci, int len)
#else
int new_len = (len + 1) * 2;
#endif
ci->line = MEM_recallocN_id(ci->line, new_len, "console line");
ci->line = static_cast<char *>(MEM_recallocN_id(ci->line, new_len, "console line"));
ci->len_alloc = new_len;
}
}
@ -323,7 +325,7 @@ static bool console_line_column_from_index(
ConsoleLine *cl;
int offset = 0;
for (cl = sc->scrollback.last; cl; cl = cl->prev) {
for (cl = static_cast<ConsoleLine *>(sc->scrollback.last); cl; cl = cl->prev) {
offset += cl->len + 1;
if (offset >= pos) {
break;
@ -338,7 +340,7 @@ static bool console_line_column_from_index(
return true;
}
*r_cl = NULL;
*r_cl = nullptr;
*r_cl_offset = -1;
*r_col = -1;
return false;
@ -354,7 +356,7 @@ static const EnumPropertyItem console_move_type_items[] = {
{NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
{PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
{NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
static int console_move_exec(bContext *C, wmOperator *op)
@ -434,13 +436,13 @@ static int console_insert_exec(bContext *C, wmOperator *op)
SpaceConsole *sc = CTX_wm_space_console(C);
ARegion *region = CTX_wm_region(C);
ConsoleLine *ci = console_history_verify(C);
char *str = RNA_string_get_alloc(op->ptr, "text", NULL, 0, NULL);
char *str = RNA_string_get_alloc(op->ptr, "text", nullptr, 0, nullptr);
int len;
if (str[0] == '\t' && str[1] == '\0') {
len = TAB_LENGTH;
MEM_freeN(str);
str = MEM_mallocN(len + 1, "insert_exec");
str = static_cast<char *>(MEM_mallocN(len + 1, "insert_exec"));
memset(str, ' ', len);
str[len] = '\0';
}
@ -518,7 +520,7 @@ void CONSOLE_OT_insert(wmOperatorType *ot)
/* properties */
prop = RNA_def_string(
ot->srna, "text", NULL, 0, "Text", "Text to insert at the cursor position");
ot->srna, "text", nullptr, 0, "Text", "Text to insert at the cursor position");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@ -526,7 +528,7 @@ void CONSOLE_OT_insert(wmOperatorType *ot)
/** \name Indent or Autocomplete Operator
* \{ */
static int console_indent_or_autocomplete_exec(bContext *C, wmOperator *UNUSED(op))
static int console_indent_or_autocomplete_exec(bContext *C, wmOperator * /*op*/)
{
ConsoleLine *ci = console_history_verify(C);
bool text_before_cursor = false;
@ -542,10 +544,10 @@ static int console_indent_or_autocomplete_exec(bContext *C, wmOperator *UNUSED(o
}
if (text_before_cursor) {
WM_operator_name_call(C, "CONSOLE_OT_autocomplete", WM_OP_INVOKE_DEFAULT, NULL, NULL);
WM_operator_name_call(C, "CONSOLE_OT_autocomplete", WM_OP_INVOKE_DEFAULT, nullptr, nullptr);
}
else {
WM_operator_name_call(C, "CONSOLE_OT_indent", WM_OP_EXEC_DEFAULT, NULL, NULL);
WM_operator_name_call(C, "CONSOLE_OT_indent", WM_OP_EXEC_DEFAULT, nullptr, nullptr);
}
return OPERATOR_FINISHED;
}
@ -571,7 +573,7 @@ void CONSOLE_OT_indent_or_autocomplete(wmOperatorType *ot)
/** \name Indent Operator
* \{ */
static int console_indent_exec(bContext *C, wmOperator *UNUSED(op))
static int console_indent_exec(bContext *C, wmOperator * /*op*/)
{
SpaceConsole *sc = CTX_wm_space_console(C);
ARegion *region = CTX_wm_region(C);
@ -618,7 +620,7 @@ void CONSOLE_OT_indent(wmOperatorType *ot)
/** \} */
static int console_unindent_exec(bContext *C, wmOperator *UNUSED(op))
static int console_unindent_exec(bContext *C, wmOperator * /*op*/)
{
SpaceConsole *sc = CTX_wm_space_console(C);
ARegion *region = CTX_wm_region(C);
@ -675,7 +677,7 @@ static const EnumPropertyItem console_delete_type_items[] = {
{DEL_PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
{DEL_NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
{DEL_PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
static int console_delete_exec(bContext *C, wmOperator *op)
@ -773,7 +775,7 @@ void CONSOLE_OT_delete(wmOperatorType *ot)
"Which part of the text to delete");
}
static int console_clear_line_exec(bContext *C, wmOperator *UNUSED(op))
static int console_clear_line_exec(bContext *C, wmOperator * /*op*/)
{
SpaceConsole *sc = CTX_wm_space_console(C);
ARegion *region = CTX_wm_region(C);
@ -784,7 +786,7 @@ static int console_clear_line_exec(bContext *C, wmOperator *UNUSED(op))
}
console_history_add(sc, ci);
console_history_add(sc, NULL);
console_history_add(sc, nullptr);
console_select_offset(sc, -ci->len);
console_textview_update_rect(sc, region);
@ -821,13 +823,13 @@ static int console_clear_exec(bContext *C, wmOperator *op)
if (scrollback) { /* Last item in history. */
while (sc->scrollback.first) {
console_scrollback_free(sc, sc->scrollback.first);
console_scrollback_free(sc, static_cast<ConsoleLine *>(sc->scrollback.first));
}
}
if (history) {
while (sc->history.first) {
console_history_free(sc, sc->history.first);
console_history_free(sc, static_cast<ConsoleLine *>(sc->history.first));
}
console_history_verify(C);
}
@ -850,8 +852,8 @@ void CONSOLE_OT_clear(wmOperatorType *ot)
ot->poll = ED_operator_console_active;
/* properties */
RNA_def_boolean(ot->srna, "scrollback", 1, "Scrollback", "Clear the scrollback history");
RNA_def_boolean(ot->srna, "history", 0, "History", "Clear the command history");
RNA_def_boolean(ot->srna, "scrollback", true, "Scrollback", "Clear the scrollback history");
RNA_def_boolean(ot->srna, "history", false, "History", "Clear the command history");
}
/* the python exec operator uses this */
@ -876,12 +878,12 @@ static int console_history_cycle_exec(bContext *C, wmOperator *op)
}
if (reverse) { /* last item in history */
ci = sc->history.last;
ci = static_cast<ConsoleLine *>(sc->history.last);
BLI_remlink(&sc->history, ci);
BLI_addhead(&sc->history, ci);
}
else {
ci = sc->history.first;
ci = static_cast<ConsoleLine *>(sc->history.first);
BLI_remlink(&sc->history, ci);
BLI_addtail(&sc->history, ci);
}
@ -895,7 +897,7 @@ static int console_history_cycle_exec(bContext *C, wmOperator *op)
console_history_add(sc, (ConsoleLine *)sc->history.last);
}
ci = sc->history.last;
ci = static_cast<ConsoleLine *>(sc->history.last);
console_select_offset(sc, ci->len - prev_len);
/* could be wrapped so update scroll rect */
@ -919,7 +921,7 @@ void CONSOLE_OT_history_cycle(wmOperatorType *ot)
ot->poll = ED_operator_console_active;
/* properties */
RNA_def_boolean(ot->srna, "reverse", 0, "Reverse", "Reverse cycle history");
RNA_def_boolean(ot->srna, "reverse", false, "Reverse", "Reverse cycle history");
}
/* the python exec operator uses this */
@ -930,7 +932,7 @@ static int console_history_append_exec(bContext *C, wmOperator *op)
ScrArea *area = CTX_wm_area(C);
ConsoleLine *ci = console_history_verify(C);
/* own this text in the new line, don't free */
char *str = RNA_string_get_alloc(op->ptr, "text", NULL, 0, NULL);
char *str = RNA_string_get_alloc(op->ptr, "text", nullptr, 0, nullptr);
int cursor = RNA_int_get(op->ptr, "current_character");
const bool rem_dupes = RNA_boolean_get(op->ptr, "remove_duplicates");
int prev_len = ci->len;
@ -948,7 +950,7 @@ static int console_history_append_exec(bContext *C, wmOperator *op)
}
}
ci = console_history_add_str(sc, str, 1); /* own the string */
ci = console_history_add_str(sc, str, true); /* own the string */
console_select_offset(sc, ci->len - prev_len);
console_line_cursor_set(ci, cursor);
@ -975,12 +977,12 @@ void CONSOLE_OT_history_append(wmOperatorType *ot)
ot->poll = ED_operator_console_active;
/* properties */
RNA_def_string(ot->srna, "text", NULL, 0, "Text", "Text to insert at the cursor position");
RNA_def_string(ot->srna, "text", nullptr, 0, "Text", "Text to insert at the cursor position");
RNA_def_int(
ot->srna, "current_character", 0, 0, INT_MAX, "Cursor", "The index of the cursor", 0, 10000);
RNA_def_boolean(ot->srna,
"remove_duplicates",
0,
false,
"Remove Duplicates",
"Remove duplicate items in the history");
}
@ -993,12 +995,12 @@ static int console_scrollback_append_exec(bContext *C, wmOperator *op)
ConsoleLine *ci;
/* own this text in the new line, don't free */
char *str = RNA_string_get_alloc(op->ptr, "text", NULL, 0, NULL);
char *str = RNA_string_get_alloc(op->ptr, "text", nullptr, 0, nullptr);
int type = RNA_enum_get(op->ptr, "type");
console_history_verify(C);
ci = console_scrollback_add_str(sc, str, 1); /* own the string */
ci = console_scrollback_add_str(sc, str, true); /* own the string */
ci->type = type;
console_scrollback_limit(sc);
@ -1022,7 +1024,7 @@ void CONSOLE_OT_scrollback_append(wmOperatorType *ot)
{CONSOLE_LINE_INPUT, "INPUT", 0, "Input", ""},
{CONSOLE_LINE_INFO, "INFO", 0, "Information", ""},
{CONSOLE_LINE_ERROR, "ERROR", 0, "Error", ""},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
@ -1035,7 +1037,7 @@ void CONSOLE_OT_scrollback_append(wmOperatorType *ot)
ot->poll = ED_operator_console_active;
/* properties */
RNA_def_string(ot->srna, "text", NULL, 0, "Text", "Text to insert at the cursor position");
RNA_def_string(ot->srna, "text", nullptr, 0, "Text", "Text to insert at the cursor position");
RNA_def_enum(ot->srna,
"type",
console_line_type_items,
@ -1044,15 +1046,15 @@ void CONSOLE_OT_scrollback_append(wmOperatorType *ot)
"Console output type");
}
static int console_copy_exec(bContext *C, wmOperator *UNUSED(op))
static int console_copy_exec(bContext *C, wmOperator * /*op*/)
{
SpaceConsole *sc = CTX_wm_space_console(C);
char *buf = console_select_to_buffer(sc);
if (buf == NULL) {
if (buf == nullptr) {
return OPERATOR_CANCELLED;
}
WM_clipboard_text_set(buf, 0);
WM_clipboard_text_set(buf, false);
MEM_freeN(buf);
return OPERATOR_FINISHED;
}
@ -1080,7 +1082,7 @@ static int console_paste_exec(bContext *C, wmOperator *op)
int buf_str_len;
char *buf_str = WM_clipboard_text_get(selection, true, &buf_str_len);
if (buf_str == NULL) {
if (buf_str == nullptr) {
return OPERATOR_CANCELLED;
}
if (*buf_str == '\0') {
@ -1093,7 +1095,7 @@ static int console_paste_exec(bContext *C, wmOperator *op)
buf_step = (char *)BLI_strchr_or_end(buf, '\n');
const int buf_len = buf_step - buf;
if (buf != buf_str) {
WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, NULL, NULL);
WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, nullptr, nullptr);
ci = console_history_verify(C);
}
console_line_insert(ci, buf, buf_len);
@ -1125,20 +1127,20 @@ void CONSOLE_OT_paste(wmOperatorType *ot)
PropertyRNA *prop;
prop = RNA_def_boolean(ot->srna,
"selection",
0,
false,
"Selection",
"Paste text selected elsewhere rather than copied (X11/Wayland only)");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
typedef struct SetConsoleCursor {
struct SetConsoleCursor {
int sel_old[2];
int sel_init;
} SetConsoleCursor;
};
/* TODO: cursor placement without selection. */
static void console_cursor_set_to_pos(
SpaceConsole *sc, ARegion *region, SetConsoleCursor *scu, const int mval[2], int UNUSED(sel))
SpaceConsole *sc, ARegion *region, SetConsoleCursor *scu, const int mval[2], int /*sel*/)
{
int pos;
pos = console_char_pick(sc, region, mval);
@ -1166,7 +1168,7 @@ static void console_modal_select_apply(bContext *C, wmOperator *op, const wmEven
{
SpaceConsole *sc = CTX_wm_space_console(C);
ARegion *region = CTX_wm_region(C);
SetConsoleCursor *scu = op->customdata;
SetConsoleCursor *scu = static_cast<SetConsoleCursor *>(op->customdata);
int mval[2];
int sel_prev[2];
@ -1187,7 +1189,7 @@ static void console_modal_select_apply(bContext *C, wmOperator *op, const wmEven
static void console_cursor_set_exit(bContext *C, wmOperator *op)
{
SpaceConsole *sc = CTX_wm_space_console(C);
SetConsoleCursor *scu = op->customdata;
SetConsoleCursor *scu = static_cast<SetConsoleCursor *>(op->customdata);
console_select_update_primary_clipboard(sc);
@ -1201,7 +1203,7 @@ static int console_modal_select_invoke(bContext *C, wmOperator *op, const wmEven
SetConsoleCursor *scu;
op->customdata = MEM_callocN(sizeof(SetConsoleCursor), "SetConsoleCursor");
scu = op->customdata;
scu = static_cast<SetConsoleCursor *>(op->customdata);
scu->sel_old[0] = sc->sel_start;
scu->sel_old[1] = sc->sel_end;
@ -1253,12 +1255,12 @@ void CONSOLE_OT_select_set(wmOperatorType *ot)
ot->poll = ED_operator_console_active;
}
static int console_selectword_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
static int console_selectword_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
{
SpaceConsole *sc = CTX_wm_space_console(C);
ARegion *region = CTX_wm_region(C);
ConsoleLine cl_dummy = {NULL};
ConsoleLine cl_dummy = {nullptr};
ConsoleLine *cl;
int ret = OPERATOR_CANCELLED;
int pos, offset, n;

View File

@ -6,8 +6,8 @@
* \ingroup spconsole
*/
#include <stdio.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include "MEM_guardedalloc.h"
@ -32,29 +32,29 @@
#include "BLO_read_write.h"
#include "console_intern.h" /* own include */
#include "console_intern.hh" /* own include */
/* ******************** default callbacks for console space ***************** */
static SpaceLink *console_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
static SpaceLink *console_create(const ScrArea * /*area*/, const Scene * /*scene*/)
{
ARegion *region;
SpaceConsole *sconsole;
sconsole = MEM_callocN(sizeof(SpaceConsole), "initconsole");
sconsole = static_cast<SpaceConsole *>(MEM_callocN(sizeof(SpaceConsole), "initconsole"));
sconsole->spacetype = SPACE_CONSOLE;
sconsole->lheight = 14;
/* header */
region = MEM_callocN(sizeof(ARegion), "header for console");
region = static_cast<ARegion *>(MEM_callocN(sizeof(ARegion), "header for console"));
BLI_addtail(&sconsole->regionbase, region);
region->regiontype = RGN_TYPE_HEADER;
region->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
/* main region */
region = MEM_callocN(sizeof(ARegion), "main region for text");
region = static_cast<ARegion *>(MEM_callocN(sizeof(ARegion), "main region for text"));
BLI_addtail(&sconsole->regionbase, region);
region->regiontype = RGN_TYPE_WINDOW;
@ -73,26 +73,26 @@ static SpaceLink *console_create(const ScrArea *UNUSED(area), const Scene *UNUSE
return (SpaceLink *)sconsole;
}
/* not spacelink itself */
/* Doesn't free the space-link itself. */
static void console_free(SpaceLink *sl)
{
SpaceConsole *sc = (SpaceConsole *)sl;
while (sc->scrollback.first) {
console_scrollback_free(sc, sc->scrollback.first);
console_scrollback_free(sc, static_cast<ConsoleLine *>(sc->scrollback.first));
}
while (sc->history.first) {
console_history_free(sc, sc->history.first);
console_history_free(sc, static_cast<ConsoleLine *>(sc->history.first));
}
}
/* spacetype; init callback */
static void console_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area)) {}
static void console_init(wmWindowManager * /*wm*/, ScrArea * /*area*/) {}
static SpaceLink *console_duplicate(SpaceLink *sl)
{
SpaceConsole *sconsolen = MEM_dupallocN(sl);
SpaceConsole *sconsolen = static_cast<SpaceConsole *>(MEM_dupallocN(sl));
/* clear or remove stuff from old */
@ -138,7 +138,7 @@ static void console_main_region_init(wmWindowManager *wm, ARegion *region)
}
/* same as 'text_cursor' */
static void console_cursor(wmWindow *win, ScrArea *UNUSED(area), ARegion *region)
static void console_cursor(wmWindow *win, ScrArea * /*area*/, ARegion *region)
{
int wmcursor = WM_CURSOR_TEXT_EDIT;
const wmEvent *event = win->eventstate;
@ -151,12 +151,12 @@ static void console_cursor(wmWindow *win, ScrArea *UNUSED(area), ARegion *region
/* ************* dropboxes ************* */
static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
static bool id_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
{
return WM_drag_get_local_ID(drag, 0) != NULL;
return WM_drag_get_local_ID(drag, 0) != nullptr;
}
static void id_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
static void id_drop_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_get_local_ID(drag, 0);
@ -166,12 +166,12 @@ static void id_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
MEM_freeN(text);
}
static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
static bool path_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
{
return (drag->type == WM_DRAG_PATH);
}
static void path_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
static void path_drop_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
char pathname[FILE_MAX + 2];
SNPRINTF(pathname, "\"%s\"", WM_drag_get_path(drag));
@ -179,12 +179,12 @@ static void path_drop_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop)
}
/* this region dropbox definition */
static void console_dropboxes(void)
static void console_dropboxes()
{
ListBase *lb = WM_dropboxmap_find("Console", SPACE_CONSOLE, RGN_TYPE_WINDOW);
WM_dropbox_add(lb, "CONSOLE_OT_insert", id_drop_poll, id_drop_copy, NULL, NULL);
WM_dropbox_add(lb, "CONSOLE_OT_insert", path_drop_poll, path_drop_copy, NULL, NULL);
WM_dropbox_add(lb, "CONSOLE_OT_insert", id_drop_poll, id_drop_copy, nullptr, nullptr);
WM_dropbox_add(lb, "CONSOLE_OT_insert", path_drop_poll, path_drop_copy, nullptr, nullptr);
}
/* ************* end drop *********** */
@ -196,7 +196,8 @@ static void console_main_region_draw(const bContext *C, ARegion *region)
View2D *v2d = &region->v2d;
if (BLI_listbase_is_empty(&sc->scrollback)) {
WM_operator_name_call((bContext *)C, "CONSOLE_OT_banner", WM_OP_EXEC_DEFAULT, NULL, NULL);
WM_operator_name_call(
(bContext *)C, "CONSOLE_OT_banner", WM_OP_EXEC_DEFAULT, nullptr, nullptr);
}
/* clear and setup matrix */
@ -214,10 +215,10 @@ static void console_main_region_draw(const bContext *C, ARegion *region)
UI_view2d_view_restore(C);
/* scrollers */
UI_view2d_scrollers_draw(v2d, NULL);
UI_view2d_scrollers_draw(v2d, nullptr);
}
static void console_operatortypes(void)
static void console_operatortypes()
{
/* console_ops.c */
WM_operatortype_append(CONSOLE_OT_move);
@ -249,7 +250,7 @@ static void console_keymap(wmKeyConfig *keyconf)
/****************** header region ******************/
/* add handlers, stuff you only do once or on area/region changes */
static void console_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
static void console_header_region_init(wmWindowManager * /*wm*/, ARegion *region)
{
ED_region_header_init(region);
}
@ -272,7 +273,7 @@ static void console_main_region_listener(const wmRegionListenerParams *params)
if (wmn->action == NA_EDITED) {
if ((wmn->reference && area) && (wmn->reference == area->spacedata.first)) {
/* we've modified the geometry (font size), re-calculate rect */
console_textview_update_rect(wmn->reference, region);
console_textview_update_rect(static_cast<SpaceConsole *>(wmn->reference), region);
ED_region_tag_redraw(region);
}
}
@ -316,14 +317,14 @@ static void console_space_blend_write(BlendWriter *writer, SpaceLink *sl)
LISTBASE_FOREACH (ConsoleLine *, cl, &con->history) {
/* 'len_alloc' is invalid on write, set from 'len' on read */
BLO_write_struct(writer, ConsoleLine, cl);
BLO_write_raw(writer, (size_t)cl->len + 1, cl->line);
BLO_write_raw(writer, size_t(cl->len) + 1, cl->line);
}
BLO_write_struct(writer, SpaceConsole, sl);
}
void ED_spacetype_console(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype console");
SpaceType *st = static_cast<SpaceType *>(MEM_callocN(sizeof(SpaceType), "spacetype console"));
ARegionType *art;
st->spaceid = SPACE_CONSOLE;
@ -340,7 +341,7 @@ void ED_spacetype_console(void)
st->blend_write = console_space_blend_write;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype console region");
art = static_cast<ARegionType *>(MEM_callocN(sizeof(ARegionType), "spacetype console region"));
art->regionid = RGN_TYPE_WINDOW;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D;
@ -353,7 +354,7 @@ void ED_spacetype_console(void)
BLI_addhead(&st->regiontypes, art);
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype console region");
art = static_cast<ARegionType *>(MEM_callocN(sizeof(ARegionType), "spacetype console region"));
art->regionid = RGN_TYPE_HEADER;
art->prefsizey = HEADERY;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;

View File

@ -39,7 +39,6 @@
#include "RNA_access.h"
#include "RNA_prototypes.h"
#include "ED_asset_handle.h"
#include "ED_fileselect.h"
#include "ED_screen.h"
@ -156,17 +155,10 @@ static void file_but_enable_drag(uiBut *but,
}
else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS &&
(file->typeflag & FILE_TYPE_ASSET) != 0) {
char blend_path[FILE_MAX_LIBEXTRA];
if (BKE_blendfile_library_path_explode(path, blend_path, nullptr, nullptr)) {
const int import_method = ED_fileselect_asset_import_method_get(sfile, file);
BLI_assert(import_method > -1);
const int import_method = ED_fileselect_asset_import_method_get(sfile, file);
BLI_assert(import_method > -1);
AssetHandle asset{};
asset.file_data = file;
UI_but_drag_set_asset(
but, &asset, BLI_strdup(blend_path), import_method, icon, preview_image, scale);
}
UI_but_drag_set_asset(but, file->asset, import_method, icon, preview_image, scale);
}
else if (preview_image) {
UI_but_drag_set_image(but, path, icon, preview_image, scale);

View File

@ -3187,7 +3187,7 @@ static void filelist_readjob_list_lib_add_datablock(FileListReadJob *job_params,
datablock_info->free_asset_data = false;
entry->asset = &job_params->load_asset_library->add_external_asset(
entry->relpath, datablock_info->name, std::move(metadata));
entry->relpath, datablock_info->name, idcode, std::move(metadata));
}
}
}

View File

@ -107,7 +107,7 @@ static SpaceLink *file_create(const ScrArea *UNUSED(area), const Scene *UNUSED(s
return (SpaceLink *)sfile;
}
/* not spacelink itself */
/* Doesn't free the space-link itself. */
static void file_free(SpaceLink *sl)
{
SpaceFile *sfile = (SpaceFile *)sl;

View File

@ -2183,7 +2183,7 @@ void GRAPH_OT_frame_jump(wmOperatorType *ot)
static bool find_closest_frame(const FCurve *fcu,
const float frame,
const bool next,
float *closest_frame)
float *r_closest_frame)
{
bool replace;
int bezt_index = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, frame, fcu->totvert, &replace);
@ -2205,7 +2205,7 @@ static bool find_closest_frame(const FCurve *fcu,
bezt = &fcu->bezt[bezt_index - 1];
}
*closest_frame = bezt->vec[1][0];
*r_closest_frame = bezt->vec[1][0];
return true;
}

View File

@ -121,7 +121,7 @@ static SpaceLink *graph_create(const ScrArea *UNUSED(area), const Scene *scene)
return (SpaceLink *)sipo;
}
/* not spacelink itself */
/* Doesn't free the space-link itself. */
static void graph_free(SpaceLink *sl)
{
SpaceGraph *si = (SpaceGraph *)sl;

View File

@ -161,7 +161,7 @@ static SpaceLink *image_create(const ScrArea *UNUSED(area), const Scene *UNUSED(
return (SpaceLink *)simage;
}
/* not spacelink itself */
/* Doesn't free the space-link itself. */
static void image_free(SpaceLink *sl)
{
SpaceImage *simage = (SpaceImage *)sl;

View File

@ -28,15 +28,15 @@ set(INC_SYS
)
set(SRC
info_draw.c
info_ops.c
info_report.c
info_draw.cc
info_ops.cc
info_report.cc
info_stats.cc
space_info.c
textview.c
space_info.cc
textview.cc
info_intern.h
textview.h
info_intern.hh
textview.hh
)
set(LIB

Some files were not shown because too many files have changed in this diff Show More