WIP: Vulkan: Workbench #107886
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -109,17 +109,6 @@ 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):
|
||||
def draw_item(self, _context, layout, _data, item, icon, active_data, _active_propname, index):
|
||||
# assert(isinstance(item, bpy.types.ShapeKey))
|
||||
|
@ -285,50 +274,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 +662,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 +670,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,
|
||||
|
|
|
@ -2103,7 +2103,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()
|
||||
|
@ -2121,7 +2121,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")
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
|
||||
#include "DNA_ID_enums.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -22,7 +24,8 @@ typedef struct AssetRepresentation AssetRepresentation;
|
|||
|
||||
const char *AS_asset_representation_name_get(const AssetRepresentation *asset)
|
||||
ATTR_WARN_UNUSED_RESULT;
|
||||
int AS_asset_representation_id_type_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)
|
||||
|
@ -31,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().
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "BLI_string_ref.hh"
|
||||
|
||||
#include "DNA_ID_enums.h"
|
||||
#include "DNA_asset_types.h"
|
||||
|
||||
#include "AS_asset_identifier.hh"
|
||||
|
@ -87,7 +88,7 @@ class AssetRepresentation {
|
|||
std::unique_ptr<AssetWeakReference> make_weak_reference() const;
|
||||
|
||||
StringRefNull get_name() const;
|
||||
int get_id_type() 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
|
||||
|
@ -129,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);
|
||||
|
|
|
@ -89,13 +89,13 @@ StringRefNull AssetRepresentation::get_name() const
|
|||
return external_asset_.name;
|
||||
}
|
||||
|
||||
int AssetRepresentation::get_id_type() const
|
||||
ID_Type AssetRepresentation::get_id_type() const
|
||||
{
|
||||
if (is_local_id_) {
|
||||
return GS(local_asset_id_->name);
|
||||
}
|
||||
|
||||
return external_asset_.id_type;
|
||||
return ID_Type(external_asset_.id_type);
|
||||
}
|
||||
|
||||
AssetMetaData &AssetRepresentation::get_metadata() const
|
||||
|
@ -203,7 +203,7 @@ const char *AS_asset_representation_name_get(const AssetRepresentation *asset_ha
|
|||
return asset->get_name().c_str();
|
||||
}
|
||||
|
||||
int AS_asset_representation_id_type_get(const AssetRepresentation *asset_handle)
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -180,9 +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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
* \{ */
|
||||
|
|
|
@ -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()]) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -182,14 +182,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.
|
||||
*
|
||||
|
@ -204,11 +220,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. */
|
||||
}
|
||||
|
|
|
@ -62,7 +62,6 @@ enum {
|
|||
SIMFACE_NORMAL,
|
||||
SIMFACE_COPLANAR,
|
||||
SIMFACE_SMOOTH,
|
||||
SIMFACE_FACEMAP,
|
||||
SIMFACE_FREESTYLE,
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "COM_KuwaharaNode.h"
|
||||
|
||||
#include "COM_ConvolutionFilterOperation.h"
|
||||
#include "COM_FastGaussianBlurOperation.h"
|
||||
#include "COM_KuwaharaAnisotropicOperation.h"
|
||||
#include "COM_KuwaharaClassicOperation.h"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -10,7 +10,19 @@ GPU_SHADER_CREATE_INFO(compositor_read_pass_shared)
|
|||
.sampler(0, ImageType::FLOAT_2D, "input_tx")
|
||||
.compute_source("compositor_read_pass.glsl");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_read_pass)
|
||||
GPU_SHADER_CREATE_INFO(compositor_read_pass_float)
|
||||
.additional_info("compositor_read_pass_shared")
|
||||
.image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
|
||||
.define("READ_EXPRESSION(pass_color)", "vec4(pass_color.r, vec3(0.0))")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_read_pass_vector)
|
||||
.additional_info("compositor_read_pass_shared")
|
||||
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
|
||||
.define("READ_EXPRESSION(pass_color)", "pass_color")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_read_pass_color)
|
||||
.additional_info("compositor_read_pass_shared")
|
||||
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
|
||||
.define("READ_EXPRESSION(pass_color)", "pass_color")
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -38,9 +38,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
|
||||
|
|
|
@ -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);
|
|
@ -34,23 +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 <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
|
||||
|
|
|
@ -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);
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 & 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;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ ID *ED_asset_handle_get_local_id(const AssetHandle *asset_handle)
|
|||
|
||||
ID_Type ED_asset_handle_get_id_type(const AssetHandle *asset_handle)
|
||||
{
|
||||
return static_cast<ID_Type>(AS_asset_representation_id_type_get(asset_handle->file_data->asset));
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1056,11 +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);
|
||||
|
||||
bool ED_view3d_context_activate(struct bContext *C);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -30,14 +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);
|
||||
wmDragAsset *asset_drag = WM_drag_create_asset_data(asset, import_type);
|
||||
|
||||
/* FIXME: This is temporary evil solution to get scene/view-layer/etc in the copy callback of the
|
||||
* #wmDropBox.
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -226,14 +226,6 @@ 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);
|
||||
|
||||
WM_operatortype_append(OBJECT_OT_move_to_collection);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "AS_asset_catalog.hh"
|
||||
#include "AS_asset_catalog_tree.hh"
|
||||
#include "AS_asset_library.hh"
|
||||
#include "AS_asset_representation.h"
|
||||
#include "AS_asset_representation.hh"
|
||||
|
||||
#include "BLI_multi_value_map.hh"
|
||||
|
||||
|
@ -49,7 +49,7 @@ static void node_add_menu_assets_listen_fn(const wmRegionListenerParams *params)
|
|||
|
||||
struct LibraryAsset {
|
||||
AssetLibraryReference library_ref;
|
||||
AssetRepresentation &asset;
|
||||
asset_system::AssetRepresentation &asset;
|
||||
};
|
||||
|
||||
struct AssetItemTree {
|
||||
|
@ -121,11 +121,11 @@ static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node
|
|||
return {};
|
||||
}
|
||||
|
||||
ED_assetlist_iterate(all_library_ref, [&](AssetHandle asset_handle) {
|
||||
if (!ED_asset_filter_matches_asset(&type_filter, &asset_handle)) {
|
||||
ED_assetlist_iterate(all_library_ref, [&](asset_system::AssetRepresentation &asset) {
|
||||
if (!ED_asset_filter_matches_asset(&type_filter, asset)) {
|
||||
return true;
|
||||
}
|
||||
const AssetMetaData &meta_data = *ED_asset_handle_get_metadata(&asset_handle);
|
||||
const AssetMetaData &meta_data = asset.get_metadata();
|
||||
const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&meta_data, "type");
|
||||
if (tree_type == nullptr || IDP_Int(tree_type) != node_tree->type) {
|
||||
return true;
|
||||
|
@ -139,8 +139,7 @@ static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node
|
|||
if (catalog == nullptr) {
|
||||
return true;
|
||||
}
|
||||
AssetRepresentation *asset = ED_asset_handle_get_representation(&asset_handle);
|
||||
assets_per_path.add(catalog->path, LibraryAsset{all_library_ref, *asset});
|
||||
assets_per_path.add(catalog->path, LibraryAsset{all_library_ref, asset});
|
||||
return true;
|
||||
});
|
||||
|
||||
|
@ -205,10 +204,7 @@ static void node_add_catalog_assets_draw(const bContext *C, Menu *menu)
|
|||
const_cast<AssetLibraryReference *>(&item.library_ref)};
|
||||
uiLayoutSetContextPointer(col, "asset_library_ref", &library_ptr);
|
||||
|
||||
uiItemO(col,
|
||||
IFACE_(AS_asset_representation_name_get(&item.asset)),
|
||||
ICON_NONE,
|
||||
"NODE_OT_add_group_asset");
|
||||
uiItemO(col, IFACE_(item.asset.get_name().c_str()), ICON_NONE, "NODE_OT_add_group_asset");
|
||||
}
|
||||
|
||||
asset_system::AssetLibrary *all_library = get_all_library_once_available();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "AS_asset_catalog.hh"
|
||||
#include "AS_asset_library.hh"
|
||||
#include "AS_asset_representation.hh"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string_search.h"
|
||||
|
@ -62,20 +63,19 @@ static void add_node_search_listen_fn(const wmRegionListenerParams *params, void
|
|||
}
|
||||
|
||||
static void search_items_for_asset_metadata(const bNodeTree &node_tree,
|
||||
const AssetHandle asset_handle,
|
||||
const asset_system::AssetRepresentation &asset,
|
||||
nodes::GatherAddNodeSearchParams ¶ms)
|
||||
{
|
||||
const AssetMetaData &asset_data = *ED_asset_handle_get_metadata(&asset_handle);
|
||||
const AssetMetaData &asset_data = asset.get_metadata();
|
||||
const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&asset_data, "type");
|
||||
if (tree_type == nullptr || IDP_Int(tree_type) != node_tree.type) {
|
||||
return;
|
||||
}
|
||||
|
||||
const AssetRepresentation *asset = ED_asset_handle_get_representation(&asset_handle);
|
||||
params.add_single_node_item(
|
||||
IFACE_(ED_asset_handle_get_name(&asset_handle)),
|
||||
IFACE_(asset.get_name().c_str()),
|
||||
asset_data.description == nullptr ? "" : IFACE_(asset_data.description),
|
||||
[asset](const bContext &C, bNodeTree &node_tree, bNode &node) {
|
||||
[&asset](const bContext &C, bNodeTree &node_tree, bNode &node) {
|
||||
Main &bmain = *CTX_data_main(&C);
|
||||
node.flag &= ~NODE_OPTIONS;
|
||||
node.id = ED_asset_get_local_id_from_asset_or_append_and_reuse(&bmain, asset, ID_NT);
|
||||
|
@ -102,11 +102,11 @@ static void gather_search_items_for_all_assets(const bContext &C,
|
|||
|
||||
ED_assetlist_storage_fetch(&library_ref, &C);
|
||||
ED_assetlist_ensure_previews_job(&library_ref, &C);
|
||||
ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
|
||||
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
|
||||
ED_assetlist_iterate(library_ref, [&](asset_system::AssetRepresentation &asset) {
|
||||
if (!ED_asset_filter_matches_asset(&filter_settings, asset)) {
|
||||
return true;
|
||||
}
|
||||
if (!r_added_assets.add(ED_asset_handle_get_name(&asset))) {
|
||||
if (!r_added_assets.add(asset.get_name())) {
|
||||
/* If an asset with the same name has already been added, skip this. */
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "AS_asset_representation.hh"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string_search.h"
|
||||
|
||||
|
@ -148,10 +150,10 @@ static void add_existing_group_input_fn(nodes::LinkSearchOpParams ¶ms,
|
|||
*/
|
||||
static void search_link_ops_for_asset_metadata(const bNodeTree &node_tree,
|
||||
const bNodeSocket &socket,
|
||||
const AssetHandle asset_handle,
|
||||
const asset_system::AssetRepresentation &asset,
|
||||
Vector<SocketLinkOperation> &search_link_ops)
|
||||
{
|
||||
const AssetMetaData &asset_data = *ED_asset_handle_get_metadata(&asset_handle);
|
||||
const AssetMetaData &asset_data = asset.get_metadata();
|
||||
const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&asset_data, "type");
|
||||
if (tree_type == nullptr || IDP_Int(tree_type) != node_tree.type) {
|
||||
return;
|
||||
|
@ -187,13 +189,12 @@ static void search_link_ops_for_asset_metadata(const bNodeTree &node_tree,
|
|||
continue;
|
||||
}
|
||||
|
||||
AssetRepresentation *asset = ED_asset_handle_get_representation(&asset_handle);
|
||||
const StringRef asset_name = ED_asset_handle_get_name(&asset_handle);
|
||||
const StringRef asset_name = asset.get_name();
|
||||
const StringRef socket_name = socket_property->name;
|
||||
|
||||
search_link_ops.append(
|
||||
{asset_name + " " + UI_MENU_ARROW_SEP + socket_name,
|
||||
[asset, socket_property, in_out](nodes::LinkSearchOpParams ¶ms) {
|
||||
[&asset, socket_property, in_out](nodes::LinkSearchOpParams ¶ms) {
|
||||
Main &bmain = *CTX_data_main(¶ms.C);
|
||||
|
||||
bNode &node = params.add_node(params.node_tree.typeinfo->group_idname);
|
||||
|
@ -232,11 +233,11 @@ static void gather_search_link_ops_for_asset_library(const bContext &C,
|
|||
|
||||
ED_assetlist_storage_fetch(&library_ref, &C);
|
||||
ED_assetlist_ensure_previews_job(&library_ref, &C);
|
||||
ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
|
||||
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
|
||||
ED_assetlist_iterate(library_ref, [&](asset_system::AssetRepresentation &asset) {
|
||||
if (!ED_asset_filter_matches_asset(&filter_settings, asset)) {
|
||||
return true;
|
||||
}
|
||||
if (skip_local && ED_asset_handle_get_local_id(&asset) != nullptr) {
|
||||
if (skip_local && asset.is_local_id()) {
|
||||
return true;
|
||||
}
|
||||
search_link_ops_for_asset_metadata(node_tree, socket, asset, search_link_ops);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <numeric>
|
||||
|
||||
#include "AS_asset_representation.h"
|
||||
#include "AS_asset_representation.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
@ -379,13 +380,14 @@ void NODE_OT_add_group(wmOperatorType *ot)
|
|||
* \{ */
|
||||
|
||||
static bool add_node_group_asset(const bContext &C,
|
||||
const AssetRepresentation *asset,
|
||||
const AssetRepresentation &asset_c_handle,
|
||||
ReportList &reports)
|
||||
{
|
||||
Main &bmain = *CTX_data_main(&C);
|
||||
SpaceNode &snode = *CTX_wm_space_node(&C);
|
||||
bNodeTree &edit_tree = *snode.edittree;
|
||||
|
||||
auto &asset = reinterpret_cast<const asset_system::AssetRepresentation &>(asset_c_handle);
|
||||
bNodeTree *node_group = reinterpret_cast<bNodeTree *>(
|
||||
ED_asset_get_local_id_from_asset_or_append_and_reuse(&bmain, asset, ID_NT));
|
||||
if (!node_group) {
|
||||
|
@ -443,7 +445,7 @@ static int node_add_group_asset_invoke(bContext *C, wmOperator *op, const wmEven
|
|||
|
||||
snode.runtime->cursor /= UI_SCALE_FAC;
|
||||
|
||||
if (!add_node_group_asset(*C, asset, *op->reports)) {
|
||||
if (!add_node_group_asset(*C, *asset, *op->reports)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
set(INC
|
||||
../include
|
||||
../../asset_system
|
||||
../../blenfont
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
|
|
|
@ -41,87 +41,3 @@
|
|||
uchar view3d_camera_border_hack_col[3];
|
||||
bool view3d_camera_border_hack_test = false;
|
||||
#endif
|
||||
|
||||
/* ***************** BACKBUF SEL (BBS) ********* */
|
||||
|
||||
void ED_draw_object_facemap(Depsgraph *depsgraph,
|
||||
Object *ob,
|
||||
const float col[4],
|
||||
const int facemap)
|
||||
{
|
||||
/* happens on undo */
|
||||
if (ob->type != OB_MESH || !ob->data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Mesh *me = static_cast<const Mesh *>(ob->data);
|
||||
{
|
||||
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||
const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
|
||||
if (me_eval != nullptr) {
|
||||
me = me_eval;
|
||||
}
|
||||
}
|
||||
|
||||
GPU_front_facing(ob->transflag & OB_NEG_SCALE);
|
||||
|
||||
/* Just to create the data to pass to immediate mode! (sigh) */
|
||||
const int *facemap_data = static_cast<const int *>(CustomData_get_layer(&me->pdata, CD_FACEMAP));
|
||||
if (facemap_data) {
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
const float(*positions)[3] = BKE_mesh_vert_positions(me);
|
||||
const blender::OffsetIndices polys = me->polys();
|
||||
const blender::Span<int> corner_verts = me->corner_verts();
|
||||
const blender::Span<MLoopTri> looptris = me->looptris();
|
||||
|
||||
facemap_data = static_cast<const int *>(CustomData_get_layer(&me->pdata, CD_FACEMAP));
|
||||
|
||||
/* Make a batch and free it each time for now. */
|
||||
const int looptris_len = poly_to_tri_count(polys.size(), corner_verts.size());
|
||||
const int vbo_len_capacity = looptris_len * 3;
|
||||
int vbo_len_used = 0;
|
||||
|
||||
GPUVertFormat format_pos = {0};
|
||||
const uint pos_id = GPU_vertformat_attr_add(
|
||||
&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
|
||||
GPUVertBuf *vbo_pos = GPU_vertbuf_create_with_format(&format_pos);
|
||||
GPU_vertbuf_data_alloc(vbo_pos, vbo_len_capacity);
|
||||
|
||||
GPUVertBufRaw pos_step;
|
||||
GPU_vertbuf_attr_get_raw_data(vbo_pos, pos_id, &pos_step);
|
||||
|
||||
int tri_index = 0;
|
||||
for (const int i : polys.index_range()) {
|
||||
if (facemap_data[i] == facemap) {
|
||||
for (int j = 2; j < polys[i].size(); j++) {
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
|
||||
positions[corner_verts[looptris[tri_index].tri[0]]]);
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
|
||||
positions[corner_verts[looptris[tri_index].tri[1]]]);
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
|
||||
positions[corner_verts[looptris[tri_index].tri[2]]]);
|
||||
vbo_len_used += 3;
|
||||
tri_index++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tri_index += polys[i].size() - 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (vbo_len_capacity != vbo_len_used) {
|
||||
GPU_vertbuf_data_resize(vbo_pos, vbo_len_used);
|
||||
}
|
||||
|
||||
GPUBatch *draw_batch = GPU_batch_create(GPU_PRIM_TRIS, vbo_pos, nullptr);
|
||||
GPU_batch_program_set_builtin(draw_batch, GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
GPU_batch_uniform_4fv(draw_batch, "color", col);
|
||||
GPU_batch_draw(draw_batch);
|
||||
GPU_batch_discard(draw_batch);
|
||||
GPU_vertbuf_discard(vbo_pos);
|
||||
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "AS_asset_representation.h"
|
||||
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_defaults.h"
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
|
@ -496,7 +498,7 @@ static ID_Type view3d_drop_id_in_main_region_poll_get_id_type(bContext *C,
|
|||
|
||||
wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, 0);
|
||||
if (asset_drag) {
|
||||
return ID_Type(asset_drag->id_type);
|
||||
return AS_asset_representation_id_type_get(asset_drag->asset);
|
||||
}
|
||||
|
||||
return ID_Type(0);
|
||||
|
@ -731,7 +733,8 @@ static bool view3d_geometry_nodes_drop_poll(bContext *C, wmDrag *drag, const wmE
|
|||
if (!asset_data) {
|
||||
return false;
|
||||
}
|
||||
const IDProperty *tree_type = BKE_asset_metadata_idprop_find(asset_data->metadata, "type");
|
||||
const AssetMetaData *metadata = AS_asset_representation_metadata_get(asset_data->asset);
|
||||
const IDProperty *tree_type = BKE_asset_metadata_idprop_find(metadata, "type");
|
||||
if (!tree_type || IDP_Int(tree_type) != NTREE_GEOMETRY) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -581,7 +581,7 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
|
|||
return false;
|
||||
}
|
||||
if (value == TFM_MODAL_ADD_SNAP) {
|
||||
if (!validSnap(t)) {
|
||||
if (!(t->tsnap.status & SNAP_TARGET_FOUND)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,8 @@ typedef enum {
|
|||
|
||||
/** Do not display Xform gizmo even though it is available. */
|
||||
T_NO_GIZMO = 1 << 24,
|
||||
|
||||
T_DRAW_SNAP_SOURCE = 1 << 25,
|
||||
} eTFlag;
|
||||
ENUM_OPERATORS(eTFlag, T_NO_GIZMO);
|
||||
|
||||
|
|
|
@ -61,12 +61,9 @@ static void snapsource_end(TransInfo *t)
|
|||
t->mouse.post = customdata->mouse_prev.post;
|
||||
t->mouse.use_virtual_mval = customdata->mouse_prev.use_virtual_mval;
|
||||
|
||||
transform_gizmo_3d_model_from_constraint_and_mode_set(t);
|
||||
|
||||
MEM_freeN(customdata);
|
||||
|
||||
t->tsnap.snap_source_fn = NULL;
|
||||
|
||||
transform_gizmo_3d_model_from_constraint_and_mode_set(t);
|
||||
tranform_snap_source_restore_context(t);
|
||||
}
|
||||
|
||||
|
@ -74,6 +71,9 @@ static void snapsource_confirm(TransInfo *t)
|
|||
{
|
||||
BLI_assert(t->modifiers & MOD_EDIT_SNAP_SOURCE);
|
||||
getSnapPoint(t, t->tsnap.snap_source);
|
||||
t->tsnap.snap_source_fn = NULL;
|
||||
t->tsnap.status |= SNAP_SOURCE_FOUND;
|
||||
t->flag |= T_DRAW_SNAP_SOURCE;
|
||||
|
||||
int mval[2];
|
||||
#ifndef RESET_TRANSFORMATION
|
||||
|
@ -180,23 +180,12 @@ void transform_mode_snap_source_init(TransInfo *t, wmOperator *UNUSED(op))
|
|||
|
||||
t->mode_info = &TransMode_snapsource;
|
||||
t->tsnap.target_operation = SCE_SNAP_TARGET_ALL;
|
||||
|
||||
if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) {
|
||||
if (t->tsnap.snap_source_fn) {
|
||||
/* Calculate the current snap source for perpendicular snap. */
|
||||
t->tsnap.snap_source_fn(t);
|
||||
}
|
||||
if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) {
|
||||
/* Fallback. */
|
||||
copy_v3_v3(t->tsnap.snap_source, t->center_global);
|
||||
t->tsnap.status |= SNAP_SOURCE_FOUND;
|
||||
}
|
||||
}
|
||||
t->tsnap.status &= ~SNAP_SOURCE_FOUND;
|
||||
|
||||
if ((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) == 0) {
|
||||
/* Initialize snap modes for geometry. */
|
||||
t->tsnap.mode &= ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID);
|
||||
t->tsnap.mode |= SCE_SNAP_MODE_GEOM & ~SCE_SNAP_MODE_FACE_NEAREST;
|
||||
t->tsnap.mode |= SCE_SNAP_MODE_GEOM;
|
||||
}
|
||||
|
||||
if (t->data_type == &TransConvertType_Mesh) {
|
||||
|
|
|
@ -174,12 +174,10 @@ void drawSnapping(const bContext *C, TransInfo *t)
|
|||
return;
|
||||
}
|
||||
|
||||
const bool draw_source = (t->spacetype == SPACE_VIEW3D) &&
|
||||
(t->tsnap.status & SNAP_SOURCE_FOUND) &&
|
||||
((t->tsnap.mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR) ||
|
||||
t->tsnap.snap_source_fn == nullptr);
|
||||
const bool draw_source = (t->tsnap.status & SNAP_SOURCE_FOUND) && (t->flag & T_DRAW_SNAP_SOURCE);
|
||||
const bool draw_target = (t->tsnap.status & (SNAP_TARGET_FOUND | SNAP_MULTI_POINTS));
|
||||
|
||||
if (!(draw_source || validSnap(t))) {
|
||||
if (!(draw_source || draw_target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -767,6 +765,10 @@ static void initSnappingMode(TransInfo *t)
|
|||
t->tsnap.mode &= ~(SCE_SNAP_MODE_FACE_RAYCAST | SCE_SNAP_MODE_FACE_NEAREST);
|
||||
}
|
||||
|
||||
if (t->tsnap.mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR) {
|
||||
t->flag |= T_DRAW_SNAP_SOURCE;
|
||||
}
|
||||
|
||||
setSnappingCallback(t);
|
||||
|
||||
if (t->spacetype == SPACE_VIEW3D) {
|
||||
|
@ -1388,7 +1390,7 @@ eSnapMode snapObjectsTransform(
|
|||
snap_object_params.use_occlusion_test = true;
|
||||
snap_object_params.use_backface_culling = (t->tsnap.flag & SCE_SNAP_BACKFACE_CULLING) != 0;
|
||||
|
||||
float *target = (t->tsnap.status & SNAP_SOURCE_FOUND) ? t->tsnap.snap_source : t->center_global;
|
||||
float *prev_co = (t->tsnap.status & SNAP_SOURCE_FOUND) ? t->tsnap.snap_source : nullptr;
|
||||
return ED_transform_snap_object_project_view3d(t->tsnap.object_context,
|
||||
t->depsgraph,
|
||||
t->region,
|
||||
|
@ -1397,7 +1399,7 @@ eSnapMode snapObjectsTransform(
|
|||
&snap_object_params,
|
||||
nullptr,
|
||||
mval,
|
||||
target,
|
||||
prev_co,
|
||||
dist_px,
|
||||
r_loc,
|
||||
r_no);
|
||||
|
|
|
@ -3294,8 +3294,10 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
|
|||
}
|
||||
}
|
||||
|
||||
if ((snap_to_flag & SCE_SNAP_MODE_FACE_NEAREST) && ELEM(nullptr, prev_co, init_co)) {
|
||||
/* No location to work with #SCE_SNAP_MODE_FACE_NEAREST. */
|
||||
if (prev_co == nullptr) {
|
||||
snap_to_flag &= ~(SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_FACE_NEAREST);
|
||||
}
|
||||
else if (init_co == nullptr) {
|
||||
snap_to_flag &= ~SCE_SNAP_MODE_FACE_NEAREST;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "testing/testing.h"
|
||||
|
||||
#include "GPU_context.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "gpu_testing.hh"
|
||||
|
||||
|
@ -199,4 +200,52 @@ static void test_framebuffer_scissor_test()
|
|||
}
|
||||
GPU_TEST(framebuffer_scissor_test);
|
||||
|
||||
/* Color each side of a cubemap with a different color. */
|
||||
static void test_framebuffer_cube()
|
||||
{
|
||||
const int SIZE = 32;
|
||||
GPU_render_begin();
|
||||
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_HOST_READ;
|
||||
GPUTexture *tex = GPU_texture_create_cube("tex", SIZE, 1, GPU_RGBA32F, usage, nullptr);
|
||||
|
||||
const float4 clear_colors[6] = {
|
||||
{0.5f, 0.0f, 0.0f, 1.0f},
|
||||
{1.0f, 0.0f, 0.0f, 1.0f},
|
||||
{0.0f, 0.5f, 0.0f, 1.0f},
|
||||
{0.0f, 1.0f, 0.0f, 1.0f},
|
||||
{0.0f, 0.0f, 0.5f, 1.0f},
|
||||
{0.0f, 0.0f, 1.0f, 1.0f},
|
||||
};
|
||||
GPUFrameBuffer *framebuffers[6] = {nullptr};
|
||||
|
||||
for (int i : IndexRange(6)) {
|
||||
GPU_framebuffer_ensure_config(&framebuffers[i],
|
||||
{
|
||||
GPU_ATTACHMENT_NONE,
|
||||
GPU_ATTACHMENT_TEXTURE_CUBEFACE(tex, i),
|
||||
});
|
||||
GPU_framebuffer_bind(framebuffers[i]);
|
||||
GPU_framebuffer_clear_color(framebuffers[i], clear_colors[i]);
|
||||
};
|
||||
|
||||
float4 *data = (float4 *)GPU_texture_read(tex, GPU_DATA_FLOAT, 0);
|
||||
for (int side : IndexRange(6)) {
|
||||
for (int pixel_index : IndexRange(SIZE * SIZE)) {
|
||||
int index = pixel_index + (SIZE * SIZE) * side;
|
||||
EXPECT_EQ(clear_colors[side], data[index]);
|
||||
}
|
||||
}
|
||||
MEM_freeN(data);
|
||||
|
||||
GPU_texture_free(tex);
|
||||
|
||||
for (int i : IndexRange(6)) {
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(framebuffers[i]);
|
||||
}
|
||||
|
||||
GPU_render_end();
|
||||
}
|
||||
GPU_TEST(framebuffer_cube)
|
||||
|
||||
} // namespace blender::gpu::tests
|
||||
|
|
|
@ -63,6 +63,52 @@ static void test_texture_read()
|
|||
}
|
||||
GPU_TEST(texture_read)
|
||||
|
||||
static void test_texture_cube()
|
||||
{
|
||||
const int SIZE = 32;
|
||||
GPU_render_begin();
|
||||
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_HOST_READ;
|
||||
GPUTexture *tex = GPU_texture_create_cube("tex", SIZE, 1, GPU_RGBA32F, usage, nullptr);
|
||||
float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
|
||||
GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
|
||||
|
||||
float4 *data = (float4 *)GPU_texture_read(tex, GPU_DATA_FLOAT, 0);
|
||||
for (int index : IndexRange(SIZE * SIZE * 6)) {
|
||||
EXPECT_EQ(clear_color, data[index]);
|
||||
}
|
||||
MEM_freeN(data);
|
||||
|
||||
GPU_texture_free(tex);
|
||||
|
||||
GPU_render_end();
|
||||
}
|
||||
GPU_TEST(texture_cube)
|
||||
|
||||
static void test_texture_cube_array()
|
||||
{
|
||||
const int SIZE = 32;
|
||||
const int ARRAY = 2;
|
||||
GPU_render_begin();
|
||||
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_HOST_READ;
|
||||
GPUTexture *tex = GPU_texture_create_cube_array(
|
||||
"tex", SIZE, ARRAY, 1, GPU_RGBA32F, usage, nullptr);
|
||||
float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
|
||||
GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
|
||||
|
||||
float4 *data = (float4 *)GPU_texture_read(tex, GPU_DATA_FLOAT, 0);
|
||||
for (int index : IndexRange(SIZE * SIZE * 6 * ARRAY)) {
|
||||
EXPECT_EQ(clear_color, data[index]);
|
||||
}
|
||||
MEM_freeN(data);
|
||||
|
||||
GPU_texture_free(tex);
|
||||
|
||||
GPU_render_end();
|
||||
}
|
||||
GPU_TEST(texture_cube_array)
|
||||
|
||||
static void test_texture_copy()
|
||||
{
|
||||
const int SIZE = 128;
|
||||
|
|
|
@ -108,7 +108,10 @@ void VKBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_
|
|||
command_buffer.dispatch(groups_x_len, groups_y_len, groups_z_len);
|
||||
}
|
||||
|
||||
void VKBackend::compute_dispatch_indirect(StorageBuf * /*indirect_buf*/) {}
|
||||
void VKBackend::compute_dispatch_indirect(StorageBuf * /*indirect_buf*/)
|
||||
{
|
||||
NOT_YET_IMPLEMENTED;
|
||||
}
|
||||
|
||||
Context *VKBackend::context_alloc(void *ghost_window, void *ghost_context)
|
||||
{
|
||||
|
|
|
@ -588,17 +588,22 @@ VkFormat to_vk_format(const GPUVertCompType type, const uint32_t size, GPUVertFe
|
|||
|
||||
VkImageType to_vk_image_type(const eGPUTextureType type)
|
||||
{
|
||||
/* See
|
||||
* https://vulkan.lunarg.com/doc/view/1.3.243.0/linux/1.3-extensions/vkspec.html#resources-image-views-compatibility
|
||||
* for reference */
|
||||
switch (type) {
|
||||
case GPU_TEXTURE_1D:
|
||||
case GPU_TEXTURE_BUFFER:
|
||||
case GPU_TEXTURE_1D_ARRAY:
|
||||
return VK_IMAGE_TYPE_1D;
|
||||
|
||||
case GPU_TEXTURE_2D:
|
||||
case GPU_TEXTURE_2D_ARRAY:
|
||||
return VK_IMAGE_TYPE_2D;
|
||||
case GPU_TEXTURE_3D:
|
||||
case GPU_TEXTURE_CUBE:
|
||||
case GPU_TEXTURE_CUBE_ARRAY:
|
||||
return VK_IMAGE_TYPE_2D;
|
||||
|
||||
case GPU_TEXTURE_3D:
|
||||
return VK_IMAGE_TYPE_3D;
|
||||
|
||||
case GPU_TEXTURE_ARRAY:
|
||||
|
@ -610,7 +615,7 @@ VkImageType to_vk_image_type(const eGPUTextureType type)
|
|||
return VK_IMAGE_TYPE_1D;
|
||||
}
|
||||
|
||||
VkImageViewType to_vk_image_view_type(const eGPUTextureType type)
|
||||
VkImageViewType to_vk_image_view_type(const eGPUTextureType type, const eImageViewUsage view_type)
|
||||
{
|
||||
switch (type) {
|
||||
case GPU_TEXTURE_1D:
|
||||
|
@ -621,13 +626,15 @@ VkImageViewType to_vk_image_view_type(const eGPUTextureType type)
|
|||
case GPU_TEXTURE_3D:
|
||||
return VK_IMAGE_VIEW_TYPE_3D;
|
||||
case GPU_TEXTURE_CUBE:
|
||||
return VK_IMAGE_VIEW_TYPE_CUBE;
|
||||
return view_type == eImageViewUsage::Attachment ? VK_IMAGE_VIEW_TYPE_2D_ARRAY :
|
||||
VK_IMAGE_VIEW_TYPE_CUBE;
|
||||
case GPU_TEXTURE_1D_ARRAY:
|
||||
return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
|
||||
case GPU_TEXTURE_2D_ARRAY:
|
||||
return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
case GPU_TEXTURE_CUBE_ARRAY:
|
||||
return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
|
||||
return view_type == eImageViewUsage::Attachment ? VK_IMAGE_VIEW_TYPE_2D_ARRAY :
|
||||
VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
|
||||
|
||||
case GPU_TEXTURE_ARRAY:
|
||||
/* GPU_TEXTURE_ARRAY should always be used together with 1D, 2D, or CUBE*/
|
||||
|
|
|
@ -23,13 +23,27 @@
|
|||
|
||||
namespace blender::gpu {
|
||||
|
||||
/**
|
||||
* Based on the usage of an Image View a different image view type should be created.
|
||||
*
|
||||
* When using a GPU_TEXTURE_CUBE as an frame buffer attachment it will be used as a
|
||||
* GPU_TEXTURE_2D_ARRAY. eg only a single side of the cube map will be attached. But when bound as
|
||||
* a shader resource the cubemap will be used.
|
||||
*/
|
||||
enum class eImageViewUsage {
|
||||
/** Image View will be used as a bindable shader resource. */
|
||||
ShaderBinding,
|
||||
/** Image View will be used as an framebuffer attachment. */
|
||||
Attachment,
|
||||
};
|
||||
|
||||
VkImageAspectFlagBits to_vk_image_aspect_flag_bits(const eGPUTextureFormat format);
|
||||
VkFormat to_vk_format(const eGPUTextureFormat format);
|
||||
VkFormat to_vk_format(const GPUVertCompType type,
|
||||
const uint32_t size,
|
||||
const GPUVertFetchMode fetch_mode);
|
||||
VkComponentMapping to_vk_component_mapping(const eGPUTextureFormat format);
|
||||
VkImageViewType to_vk_image_view_type(const eGPUTextureType type);
|
||||
VkImageViewType to_vk_image_view_type(const eGPUTextureType type, eImageViewUsage view_type);
|
||||
VkImageType to_vk_image_type(const eGPUTextureType type);
|
||||
VkClearColorValue to_vk_clear_color_value(const eGPUDataFormat format, const void *data);
|
||||
VkIndexType to_vk_index_type(const GPUIndexBufType index_type);
|
||||
|
|
|
@ -404,7 +404,7 @@ void VKFrameBuffer::render_pass_create()
|
|||
/* Ensure texture is allocated to ensure the image view. */
|
||||
VKTexture &texture = *static_cast<VKTexture *>(unwrap(attachment.tex));
|
||||
texture.ensure_allocated();
|
||||
image_views_.append(VKImageView(texture, attachment.mip, name_));
|
||||
image_views_.append(VKImageView(texture, attachment.layer, attachment.mip, name_));
|
||||
image_views[attachment_location] = image_views_.last().vk_handle();
|
||||
|
||||
VkAttachmentDescription &attachment_description =
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
namespace blender::gpu {
|
||||
|
||||
VKImageView::VKImageView(VKTexture &texture, int mip_level, StringRefNull name)
|
||||
: vk_image_view_(create_vk_image_view(texture, mip_level, name))
|
||||
VKImageView::VKImageView(VKTexture &texture, int layer, int mip_level, StringRefNull name)
|
||||
: vk_image_view_(create_vk_image_view(texture, layer, mip_level, name))
|
||||
{
|
||||
BLI_assert(vk_image_view_ != VK_NULL_HANDLE);
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ VKImageView::~VKImageView()
|
|||
}
|
||||
}
|
||||
VkImageView VKImageView::create_vk_image_view(VKTexture &texture,
|
||||
int layer,
|
||||
int mip_level,
|
||||
StringRefNull name)
|
||||
{
|
||||
|
@ -49,14 +50,15 @@ VkImageView VKImageView::create_vk_image_view(VKTexture &texture,
|
|||
VkImageViewCreateInfo image_view_info = {};
|
||||
image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
image_view_info.image = texture.vk_image_handle();
|
||||
image_view_info.viewType = to_vk_image_view_type(texture.type_get());
|
||||
image_view_info.viewType = to_vk_image_view_type(texture.type_get(),
|
||||
eImageViewUsage::Attachment);
|
||||
image_view_info.format = to_vk_format(texture.format_get());
|
||||
image_view_info.components = to_vk_component_mapping(texture.format_get());
|
||||
image_view_info.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(texture.format_get());
|
||||
image_view_info.subresourceRange.baseMipLevel = mip_level;
|
||||
image_view_info.subresourceRange.levelCount = 1;
|
||||
image_view_info.subresourceRange.baseArrayLayer = 0;
|
||||
image_view_info.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||
image_view_info.subresourceRange.baseArrayLayer = layer == -1 ? 0 : layer;
|
||||
image_view_info.subresourceRange.layerCount = 1;
|
||||
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
VkImageView image_view = VK_NULL_HANDLE;
|
||||
|
|
|
@ -20,7 +20,7 @@ class VKImageView : NonCopyable {
|
|||
VkImageView vk_image_view_ = VK_NULL_HANDLE;
|
||||
|
||||
public:
|
||||
VKImageView(VKTexture &texture, int mip_level, StringRefNull name);
|
||||
VKImageView(VKTexture &texture, int layer, int mip_level, StringRefNull name);
|
||||
|
||||
/**
|
||||
* Wrap the given vk_image_view handle. Note that the vk_image_view handle ownership is
|
||||
|
@ -38,7 +38,10 @@ class VKImageView : NonCopyable {
|
|||
}
|
||||
|
||||
private:
|
||||
static VkImageView create_vk_image_view(VKTexture &texture, int mip_level, StringRefNull name);
|
||||
static VkImageView create_vk_image_view(VKTexture &texture,
|
||||
int layer,
|
||||
int mip_level,
|
||||
StringRefNull name);
|
||||
};
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -157,6 +157,15 @@ void VKTexture::mip_range_set(int min, int max)
|
|||
flags_ |= IMAGE_VIEW_DIRTY;
|
||||
}
|
||||
|
||||
int VKTexture::layer_count()
|
||||
{
|
||||
int layers = 1;
|
||||
if (ELEM(type_, GPU_TEXTURE_CUBE, GPU_TEXTURE_CUBE_ARRAY)) {
|
||||
layers = d_;
|
||||
}
|
||||
return layers;
|
||||
}
|
||||
|
||||
void VKTexture::read_sub(int mip, eGPUDataFormat format, const int area[4], void *r_data)
|
||||
{
|
||||
VKContext &context = *VKContext::get();
|
||||
|
@ -165,7 +174,7 @@ void VKTexture::read_sub(int mip, eGPUDataFormat format, const int area[4], void
|
|||
/* Vulkan images cannot be directly mapped to host memory and requires a staging buffer. */
|
||||
VKBuffer staging_buffer;
|
||||
|
||||
size_t sample_len = area[2] * area[3];
|
||||
size_t sample_len = area[2] * area[3] * layer_count();
|
||||
size_t device_memory_size = sample_len * to_bytesize(format_);
|
||||
|
||||
staging_buffer.create(
|
||||
|
@ -179,7 +188,7 @@ void VKTexture::read_sub(int mip, eGPUDataFormat format, const int area[4], void
|
|||
region.imageExtent.depth = 1;
|
||||
region.imageSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_);
|
||||
region.imageSubresource.mipLevel = mip;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageSubresource.layerCount = layer_count();
|
||||
|
||||
VKCommandBuffer &command_buffer = context.command_buffer_get();
|
||||
command_buffer.copy(staging_buffer, *this, Span<VkBufferImageCopy>(®ion, 1));
|
||||
|
@ -192,7 +201,7 @@ void *VKTexture::read(int mip, eGPUDataFormat format)
|
|||
{
|
||||
int mip_size[3] = {1, 1, 1};
|
||||
mip_size_get(mip, mip_size);
|
||||
size_t sample_len = mip_size[0] * mip_size[1];
|
||||
size_t sample_len = mip_size[0] * mip_size[1] * layer_count();
|
||||
size_t host_memory_size = sample_len * to_bytesize(format_, format);
|
||||
|
||||
void *data = MEM_mallocN(host_memory_size, __func__);
|
||||
|
@ -372,6 +381,17 @@ static VkImageUsageFlagBits to_vk_image_usage(const eGPUTextureUsage usage,
|
|||
return result;
|
||||
}
|
||||
|
||||
static VkImageCreateFlagBits to_vk_image_create(const eGPUTextureType texture_type)
|
||||
{
|
||||
VkImageCreateFlagBits result = static_cast<VkImageCreateFlagBits>(0);
|
||||
|
||||
if (ELEM(texture_type, GPU_TEXTURE_CUBE, GPU_TEXTURE_CUBE_ARRAY)) {
|
||||
result = static_cast<VkImageCreateFlagBits>(result | VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool VKTexture::allocate()
|
||||
{
|
||||
BLI_assert(vk_image_ == VK_NULL_HANDLE);
|
||||
|
@ -379,17 +399,23 @@ bool VKTexture::allocate()
|
|||
|
||||
int extent[3] = {1, 1, 1};
|
||||
mip_size_get(0, extent);
|
||||
int layers = 1;
|
||||
if (ELEM(type_, GPU_TEXTURE_CUBE, GPU_TEXTURE_CUBE_ARRAY)) {
|
||||
layers = extent[2];
|
||||
extent[2] = 1;
|
||||
}
|
||||
|
||||
VKContext &context = *VKContext::get();
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
VkImageCreateInfo image_info = {};
|
||||
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
image_info.flags = to_vk_image_create(type_);
|
||||
image_info.imageType = to_vk_image_type(type_);
|
||||
image_info.extent.width = extent[0];
|
||||
image_info.extent.height = extent[1];
|
||||
image_info.extent.depth = extent[2];
|
||||
image_info.mipLevels = max_ii(mipmaps_, 1);
|
||||
image_info.arrayLayers = 1;
|
||||
image_info.arrayLayers = layers;
|
||||
image_info.format = to_vk_format(format_);
|
||||
/* Some platforms (NVIDIA) requires that attached textures are always tiled optimal.
|
||||
*
|
||||
|
@ -536,14 +562,15 @@ void VKTexture::image_view_update()
|
|||
VkImageViewCreateInfo image_view_info = {};
|
||||
image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
image_view_info.image = vk_image_;
|
||||
image_view_info.viewType = to_vk_image_view_type(type_);
|
||||
image_view_info.viewType = to_vk_image_view_type(type_, eImageViewUsage::ShaderBinding);
|
||||
image_view_info.format = to_vk_format(format_);
|
||||
image_view_info.components = to_vk_component_mapping(format_);
|
||||
image_view_info.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(format_);
|
||||
IndexRange mip_range = mip_map_range();
|
||||
image_view_info.subresourceRange.baseMipLevel = mip_range.first();
|
||||
image_view_info.subresourceRange.levelCount = mip_range.size();
|
||||
image_view_info.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||
image_view_info.subresourceRange.layerCount =
|
||||
ELEM(type_, GPU_TEXTURE_CUBE, GPU_TEXTURE_CUBE_ARRAY) ? d_ : VK_REMAINING_ARRAY_LAYERS;
|
||||
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
VkImageView image_view = VK_NULL_HANDLE;
|
||||
|
|
|
@ -86,6 +86,8 @@ class VKTexture : public Texture {
|
|||
*/
|
||||
bool allocate();
|
||||
|
||||
int layer_count();
|
||||
|
||||
VkImageViewType vk_image_view_type() const;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -121,7 +121,9 @@ typedef enum eCustomDataType {
|
|||
* lazily. Derived vertex and polygon normals are stored in #Mesh_Runtime.
|
||||
*/
|
||||
CD_NORMAL = 8,
|
||||
CD_FACEMAP = 9, /* exclusive face group, each face can only be part of one */
|
||||
#ifdef DNA_DEPRECATED_ALLOW
|
||||
CD_FACEMAP = 9,
|
||||
#endif
|
||||
CD_PROP_FLOAT = 10,
|
||||
CD_PROP_INT32 = 11,
|
||||
CD_PROP_STRING = 12,
|
||||
|
@ -190,7 +192,6 @@ typedef enum eCustomDataType {
|
|||
#define CD_MASK_MCOL (1 << CD_MCOL)
|
||||
#define CD_MASK_ORIGINDEX (1 << CD_ORIGINDEX)
|
||||
#define CD_MASK_NORMAL (1 << CD_NORMAL)
|
||||
#define CD_MASK_FACEMAP (1 << CD_FACEMAP)
|
||||
#define CD_MASK_PROP_FLOAT (1 << CD_PROP_FLOAT)
|
||||
#define CD_MASK_PROP_INT32 (1 << CD_PROP_INT32)
|
||||
#define CD_MASK_PROP_STRING (1 << CD_PROP_STRING)
|
||||
|
|
|
@ -56,15 +56,6 @@ typedef struct bDeformGroup {
|
|||
char flag, _pad0[7];
|
||||
} bDeformGroup;
|
||||
|
||||
/** Face Maps. */
|
||||
typedef struct bFaceMap {
|
||||
struct bFaceMap *next, *prev;
|
||||
/** MAX_VGROUP_NAME. */
|
||||
char name[64];
|
||||
char flag;
|
||||
char _pad0[7];
|
||||
} bFaceMap;
|
||||
|
||||
#define MAX_VGROUP_NAME 64
|
||||
|
||||
/* bDeformGroup->flag */
|
||||
|
@ -353,8 +344,6 @@ typedef struct Object {
|
|||
ListBase modifiers;
|
||||
/** List of GpencilModifierData structures. */
|
||||
ListBase greasepencil_modifiers;
|
||||
/** List of facemaps. */
|
||||
ListBase fmaps;
|
||||
/** List of viewport effects. Actually only used by grease pencil. */
|
||||
ListBase shader_fx;
|
||||
|
||||
|
@ -445,8 +434,7 @@ typedef struct Object {
|
|||
/** Current deformation group, NOTE: index starts at 1. */
|
||||
unsigned short actdef DNA_DEPRECATED;
|
||||
/** Current face map, NOTE: index starts at 1. */
|
||||
unsigned short actfmap;
|
||||
char _pad2[2];
|
||||
char _pad2[4];
|
||||
/** Object color (in most cases the material color is used for drawing). */
|
||||
float color[4];
|
||||
|
||||
|
|
|
@ -357,7 +357,6 @@ static void rna_AssetHandle_file_data_set(PointerRNA *ptr,
|
|||
static void rna_AssetHandle_get_full_library_path(
|
||||
// AssetHandle *asset,
|
||||
FileDirEntry *asset_file,
|
||||
AssetLibraryReference *UNUSED(asset_library), /* Deprecated. */
|
||||
char r_result[/*FILE_MAX_LIBEXTRA*/])
|
||||
{
|
||||
AssetHandle asset = {.file_data = asset_file};
|
||||
|
@ -537,13 +536,6 @@ static void rna_def_asset_handle_api(StructRNA *srna)
|
|||
RNA_def_function_flag(func, FUNC_NO_SELF);
|
||||
parm = RNA_def_pointer(func, "asset_file_handle", "FileSelectEntry", "", "");
|
||||
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||
RNA_def_pointer(
|
||||
func,
|
||||
"asset_library_ref",
|
||||
"AssetLibraryReference",
|
||||
"",
|
||||
"The asset library containing the given asset. Deprecated and optional argument, will be "
|
||||
"ignored. Kept for API compatibility only");
|
||||
parm = RNA_def_string(func, "result", NULL, FILE_MAX_LIBEXTRA, "result", "");
|
||||
RNA_def_parameter_flags(parm, PROP_THICK_WRAP, 0);
|
||||
RNA_def_function_output(func, parm);
|
||||
|
|
|
@ -694,7 +694,7 @@ static void rna_tag_animation_update(Main *bmain, ID *id)
|
|||
static void rna_FCurve_update_data_ex(ID *id, FCurve *fcu, Main *bmain)
|
||||
{
|
||||
sort_time_fcurve(fcu);
|
||||
/* TODO: Blender 4.0 should call BKE_fcurve_deduplicate_keys(fcu) here. */
|
||||
BKE_fcurve_deduplicate_keys(fcu);
|
||||
BKE_fcurve_handles_recalc(fcu);
|
||||
|
||||
rna_tag_animation_update(bmain, id);
|
||||
|
|
|
@ -86,11 +86,6 @@ static CustomData *rna_mesh_edata_helper(Mesh *me)
|
|||
return (me->edit_mesh) ? &me->edit_mesh->bm->edata : &me->edata;
|
||||
}
|
||||
|
||||
static CustomData *rna_mesh_pdata_helper(Mesh *me)
|
||||
{
|
||||
return (me->edit_mesh) ? &me->edit_mesh->bm->pdata : &me->pdata;
|
||||
}
|
||||
|
||||
static CustomData *rna_mesh_ldata_helper(Mesh *me)
|
||||
{
|
||||
return (me->edit_mesh) ? &me->edit_mesh->bm->ldata : &me->ldata;
|
||||
|
@ -106,11 +101,6 @@ static CustomData *rna_mesh_edata(const PointerRNA *ptr)
|
|||
Mesh *me = rna_mesh(ptr);
|
||||
return rna_mesh_edata_helper(me);
|
||||
}
|
||||
static CustomData *rna_mesh_pdata(const PointerRNA *ptr)
|
||||
{
|
||||
Mesh *me = rna_mesh(ptr);
|
||||
return rna_mesh_pdata_helper(me);
|
||||
}
|
||||
|
||||
static CustomData *rna_mesh_ldata(const PointerRNA *ptr)
|
||||
{
|
||||
|
@ -154,17 +144,6 @@ static void rna_MeshEdgeLayer_name_set(PointerRNA *ptr, const char *value)
|
|||
}
|
||||
}
|
||||
# endif
|
||||
static void rna_MeshPolyLayer_name_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
|
||||
if (CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) {
|
||||
BKE_id_attribute_rename(ptr->owner_id, layer->name, value, NULL);
|
||||
}
|
||||
else {
|
||||
rna_cd_layer_name_set(rna_mesh_pdata(ptr), layer, value);
|
||||
}
|
||||
}
|
||||
static void rna_MeshLoopLayer_name_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
|
@ -1356,78 +1335,6 @@ static int rna_MeshPaintMaskLayer_data_length(PointerRNA *ptr)
|
|||
|
||||
/* End paint mask */
|
||||
|
||||
/* Face maps */
|
||||
|
||||
DEFINE_CUSTOMDATA_LAYER_COLLECTION(face_map, pdata, CD_FACEMAP)
|
||||
DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(
|
||||
face_map, pdata, CD_FACEMAP, active, MeshFaceMapLayer)
|
||||
|
||||
static char *rna_MeshFaceMapLayer_path(const PointerRNA *ptr)
|
||||
{
|
||||
const CustomDataLayer *cdl = ptr->data;
|
||||
char name_esc[sizeof(cdl->name) * 2];
|
||||
BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
|
||||
return BLI_sprintfN("face_maps[\"%s\"]", name_esc);
|
||||
}
|
||||
|
||||
static void rna_MeshFaceMapLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
Mesh *me = rna_mesh(ptr);
|
||||
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
|
||||
rna_iterator_array_begin(
|
||||
iter, layer->data, sizeof(int), (me->edit_mesh) ? 0 : me->totpoly, 0, NULL);
|
||||
}
|
||||
|
||||
static int rna_MeshFaceMapLayer_data_length(PointerRNA *ptr)
|
||||
{
|
||||
Mesh *me = rna_mesh(ptr);
|
||||
return (me->edit_mesh) ? 0 : me->totpoly;
|
||||
}
|
||||
|
||||
static PointerRNA rna_Mesh_face_map_new(struct Mesh *me, ReportList *reports, const char *name)
|
||||
{
|
||||
if (BKE_mesh_ensure_facemap_customdata(me) == false) {
|
||||
BKE_report(reports, RPT_ERROR, "Currently only single face map layers are supported");
|
||||
return PointerRNA_NULL;
|
||||
}
|
||||
|
||||
CustomData *pdata = rna_mesh_pdata_helper(me);
|
||||
|
||||
int index = CustomData_get_layer_index(pdata, CD_FACEMAP);
|
||||
BLI_assert(index != -1);
|
||||
CustomDataLayer *cdl = &pdata->layers[index];
|
||||
rna_cd_layer_name_set(pdata, cdl, name);
|
||||
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create(&me->id, &RNA_MeshFaceMapLayer, cdl, &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void rna_Mesh_face_map_remove(struct Mesh *me,
|
||||
ReportList *reports,
|
||||
struct CustomDataLayer *layer)
|
||||
{
|
||||
/* just for sanity check */
|
||||
{
|
||||
CustomData *pdata = rna_mesh_pdata_helper(me);
|
||||
int index = CustomData_get_layer_index(pdata, CD_FACEMAP);
|
||||
if (index != -1) {
|
||||
CustomDataLayer *layer_test = &pdata->layers[index];
|
||||
if (layer != layer_test) {
|
||||
/* don't show name, its likely freed memory */
|
||||
BKE_report(reports, RPT_ERROR, "Face map not in mesh");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (BKE_mesh_clear_facemap_customdata(me) == false) {
|
||||
BKE_report(reports, RPT_ERROR, "Error removing face map");
|
||||
}
|
||||
}
|
||||
|
||||
/* End face maps */
|
||||
|
||||
/* poly.vertices - this is faked loop access for convenience */
|
||||
static int rna_MeshPoly_vertices_get_length(const PointerRNA *ptr,
|
||||
int length[RNA_MAX_ARRAY_DIMENSION])
|
||||
|
@ -1702,27 +1609,6 @@ static char *rna_EdgeCustomData_data_path(const PointerRNA *ptr, const char *col
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static char *rna_PolyCustomData_data_path(const PointerRNA *ptr, const char *collection, int type)
|
||||
{
|
||||
const CustomDataLayer *cdl;
|
||||
const Mesh *me = rna_mesh(ptr);
|
||||
const CustomData *pdata = rna_mesh_pdata(ptr);
|
||||
int a, b, totpoly = (me->edit_mesh) ? 0 : me->totpoly;
|
||||
|
||||
for (cdl = pdata->layers, a = 0; a < pdata->totlayer; cdl++, a++) {
|
||||
if (cdl->type == type) {
|
||||
b = ((char *)ptr->data - ((char *)cdl->data)) / CustomData_sizeof(type);
|
||||
if (b >= 0 && b < totpoly) {
|
||||
char name_esc[sizeof(cdl->name) * 2];
|
||||
BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
|
||||
return BLI_sprintfN("%s[\"%s\"].data[%d]", collection, name_esc, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *rna_LoopCustomData_data_path(const PointerRNA *ptr, const char *collection, int type)
|
||||
{
|
||||
const CustomDataLayer *cdl;
|
||||
|
@ -2053,11 +1939,6 @@ static char *rna_MeshColor_path(const PointerRNA *ptr)
|
|||
return rna_LoopCustomData_data_path(ptr, "vertex_colors", CD_PROP_BYTE_COLOR);
|
||||
}
|
||||
|
||||
static char *rna_MeshFaceMap_path(const PointerRNA *ptr)
|
||||
{
|
||||
return rna_PolyCustomData_data_path(ptr, "face_maps", CD_FACEMAP);
|
||||
}
|
||||
|
||||
/***************************************/
|
||||
|
||||
static int rna_Mesh_tot_vert_get(PointerRNA *ptr)
|
||||
|
@ -2153,10 +2034,6 @@ static void UNUSED_FUNCTION(rna_mesh_unused)(void)
|
|||
(void)rna_Mesh_uv_layer_render_index_get;
|
||||
(void)rna_Mesh_uv_layer_render_index_set;
|
||||
(void)rna_Mesh_uv_layer_render_set;
|
||||
(void)rna_Mesh_face_map_index_range;
|
||||
(void)rna_Mesh_face_map_active_index_set;
|
||||
(void)rna_Mesh_face_map_active_index_get;
|
||||
(void)rna_Mesh_face_map_active_set;
|
||||
(void)rna_Mesh_vertex_crease_index_range;
|
||||
(void)rna_Mesh_edge_crease_index_range;
|
||||
/* end unused function block */
|
||||
|
@ -3227,85 +3104,6 @@ static void rna_def_paint_mask(BlenderRNA *brna, PropertyRNA *UNUSED(cprop))
|
|||
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
|
||||
}
|
||||
|
||||
static void rna_def_face_map(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "MeshFaceMapLayer", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Mesh Face Map Layer", "Per-face map index");
|
||||
RNA_def_struct_sdna(srna, "CustomDataLayer");
|
||||
RNA_def_struct_path_func(srna, "rna_MeshFaceMapLayer_path");
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshPolyLayer_name_set");
|
||||
RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX);
|
||||
RNA_def_property_ui_text(prop, "Name", "Name of face map layer");
|
||||
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
|
||||
|
||||
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "MeshFaceMap");
|
||||
RNA_def_property_ui_text(prop, "Data", "");
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_MeshFaceMapLayer_data_begin",
|
||||
"rna_iterator_array_next",
|
||||
"rna_iterator_array_end",
|
||||
"rna_iterator_array_get",
|
||||
"rna_MeshFaceMapLayer_data_length",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* FaceMap struct */
|
||||
srna = RNA_def_struct(brna, "MeshFaceMap", NULL);
|
||||
RNA_def_struct_sdna(srna, "MIntProperty");
|
||||
RNA_def_struct_ui_text(srna, "Int Property", "");
|
||||
RNA_def_struct_path_func(srna, "rna_MeshFaceMap_path");
|
||||
|
||||
prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "i");
|
||||
RNA_def_property_ui_text(prop, "Value", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
|
||||
}
|
||||
|
||||
static void rna_def_face_maps(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
RNA_def_property_srna(cprop, "MeshFaceMapLayers");
|
||||
srna = RNA_def_struct(brna, "MeshFaceMapLayers", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Mesh Face Map Layer", "Per-face map index");
|
||||
RNA_def_struct_sdna(srna, "Mesh");
|
||||
RNA_def_struct_ui_text(srna, "Mesh Face Maps", "Collection of mesh face maps");
|
||||
|
||||
/* add this since we only ever have one layer anyway, don't bother with active_index */
|
||||
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "MeshFaceMapLayer");
|
||||
RNA_def_property_pointer_funcs(prop, "rna_Mesh_face_map_active_get", NULL, NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Active Face Map Layer", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
|
||||
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
func = RNA_def_function(srna, "new", "rna_Mesh_face_map_new");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
RNA_def_function_ui_description(func, "Add a float property layer to Mesh");
|
||||
RNA_def_string(func, "name", "Face Map", 0, "", "Face map name");
|
||||
parm = RNA_def_pointer(func, "layer", "MeshFaceMapLayer", "", "The newly created layer");
|
||||
RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
func = RNA_def_function(srna, "remove", "rna_Mesh_face_map_remove");
|
||||
RNA_def_function_ui_description(func, "Remove a face map layer");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
parm = RNA_def_pointer(func, "layer", "MeshFaceMapLayer", "", "The layer to remove");
|
||||
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
|
||||
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
|
||||
}
|
||||
|
||||
static void rna_def_looptri_poly_value(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna = RNA_def_struct(brna, "ReadOnlyInteger", NULL);
|
||||
|
@ -3552,23 +3350,6 @@ static void rna_def_mesh(BlenderRNA *brna)
|
|||
"Legacy vertex color layers. Deprecated, use color attributes instead");
|
||||
rna_def_loop_colors(brna, prop);
|
||||
|
||||
/* face-maps */
|
||||
prop = RNA_def_property(srna, "face_maps", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer");
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_Mesh_face_maps_begin",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"rna_Mesh_face_maps_length",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
RNA_def_property_struct_type(prop, "MeshFaceMapLayer");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
|
||||
RNA_def_property_ui_text(prop, "Face Map", "");
|
||||
rna_def_face_maps(brna, prop);
|
||||
|
||||
/* Skin vertices */
|
||||
prop = RNA_def_property(srna, "skin_vertices", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer");
|
||||
|
@ -3866,7 +3647,6 @@ void RNA_def_mesh(BlenderRNA *brna)
|
|||
rna_def_mpolygon(brna);
|
||||
rna_def_mloopuv(brna);
|
||||
rna_def_mloopcol(brna);
|
||||
rna_def_face_map(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include "BKE_editmesh.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_object_deform.h"
|
||||
#include "BKE_object_facemap.h"
|
||||
#include "BKE_paint.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
@ -966,91 +965,6 @@ void rna_object_vgroup_name_set(PointerRNA *ptr,
|
|||
result[0] = '\0';
|
||||
}
|
||||
|
||||
static void rna_FaceMap_name_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
bFaceMap *fmap = (bFaceMap *)ptr->data;
|
||||
STRNCPY_UTF8(fmap->name, value);
|
||||
BKE_object_facemap_unique_name(ob, fmap);
|
||||
}
|
||||
|
||||
static int rna_FaceMap_index_get(PointerRNA *ptr)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
|
||||
return BLI_findindex(&ob->fmaps, ptr->data);
|
||||
}
|
||||
|
||||
static PointerRNA rna_Object_active_face_map_get(PointerRNA *ptr)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_FaceMap, BLI_findlink(&ob->fmaps, ob->actfmap - 1));
|
||||
}
|
||||
|
||||
static int rna_Object_active_face_map_index_get(PointerRNA *ptr)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
return ob->actfmap - 1;
|
||||
}
|
||||
|
||||
static void rna_Object_active_face_map_index_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
ob->actfmap = value + 1;
|
||||
}
|
||||
|
||||
static void rna_Object_active_face_map_index_range(
|
||||
PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
|
||||
*min = 0;
|
||||
*max = max_ii(0, BLI_listbase_count(&ob->fmaps) - 1);
|
||||
}
|
||||
|
||||
void rna_object_BKE_object_facemap_name_index_get(PointerRNA *ptr, char *value, int index)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
bFaceMap *fmap;
|
||||
|
||||
fmap = BLI_findlink(&ob->fmaps, index - 1);
|
||||
|
||||
if (fmap) {
|
||||
strcpy(value, fmap->name);
|
||||
}
|
||||
else {
|
||||
value[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
int rna_object_BKE_object_facemap_name_index_length(PointerRNA *ptr, int index)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
bFaceMap *fmap;
|
||||
|
||||
fmap = BLI_findlink(&ob->fmaps, index - 1);
|
||||
return (fmap) ? strlen(fmap->name) : 0;
|
||||
}
|
||||
|
||||
void rna_object_BKE_object_facemap_name_index_set(PointerRNA *ptr, const char *value, short *index)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
*index = BKE_object_facemap_name_index(ob, value) + 1;
|
||||
}
|
||||
|
||||
void rna_object_fmap_name_set(PointerRNA *ptr, const char *value, char *result, int result_maxncpy)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
bFaceMap *fmap = BKE_object_facemap_find_name(ob, value);
|
||||
if (fmap) {
|
||||
/* No need for BLI_strncpy_utf8, since this matches an existing group. */
|
||||
BLI_strncpy(result, value, result_maxncpy);
|
||||
return;
|
||||
}
|
||||
|
||||
result[0] = '\0';
|
||||
}
|
||||
|
||||
void rna_object_uvlayer_name_set(PointerRNA *ptr,
|
||||
const char *value,
|
||||
char *result,
|
||||
|
@ -2151,71 +2065,6 @@ static float rna_VertexGroup_weight(ID *id, bDeformGroup *dg, ReportList *report
|
|||
return weight;
|
||||
}
|
||||
|
||||
static bFaceMap *rna_Object_fmap_new(Object *ob, const char *name)
|
||||
{
|
||||
bFaceMap *fmap = BKE_object_facemap_add_name(ob, name);
|
||||
|
||||
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
|
||||
|
||||
return fmap;
|
||||
}
|
||||
|
||||
static void rna_Object_fmap_remove(Object *ob, ReportList *reports, PointerRNA *fmap_ptr)
|
||||
{
|
||||
bFaceMap *fmap = fmap_ptr->data;
|
||||
if (BLI_findindex(&ob->fmaps, fmap) == -1) {
|
||||
BKE_reportf(
|
||||
reports, RPT_ERROR, "Face map '%s' not in object '%s'", fmap->name, ob->id.name + 2);
|
||||
return;
|
||||
}
|
||||
|
||||
BKE_object_facemap_remove(ob, fmap);
|
||||
RNA_POINTER_INVALIDATE(fmap_ptr);
|
||||
|
||||
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
|
||||
}
|
||||
|
||||
static void rna_Object_fmap_clear(Object *ob)
|
||||
{
|
||||
BKE_object_facemap_clear(ob);
|
||||
|
||||
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
|
||||
}
|
||||
|
||||
static void rna_FaceMap_face_add(
|
||||
ID *id, bFaceMap *fmap, ReportList *reports, int index_len, int *index)
|
||||
{
|
||||
Object *ob = (Object *)id;
|
||||
|
||||
if (BKE_object_is_in_editmode(ob)) {
|
||||
BKE_report(reports, RPT_ERROR, "FaceMap.add(): cannot be called while object is in edit mode");
|
||||
return;
|
||||
}
|
||||
|
||||
while (index_len--) {
|
||||
ED_object_facemap_face_add(ob, fmap, *index++);
|
||||
}
|
||||
|
||||
WM_main_add_notifier(NC_GEOM | ND_DATA, (ID *)ob->data);
|
||||
}
|
||||
|
||||
static void rna_FaceMap_face_remove(
|
||||
ID *id, bFaceMap *fmap, ReportList *reports, int index_len, int *index)
|
||||
{
|
||||
Object *ob = (Object *)id;
|
||||
|
||||
if (BKE_object_is_in_editmode(ob)) {
|
||||
BKE_report(reports, RPT_ERROR, "FaceMap.add(): cannot be called while object is in edit mode");
|
||||
return;
|
||||
}
|
||||
|
||||
while (index_len--) {
|
||||
ED_object_facemap_face_remove(ob, fmap, *index++);
|
||||
}
|
||||
|
||||
WM_main_add_notifier(NC_GEOM | ND_DATA, (ID *)ob->data);
|
||||
}
|
||||
|
||||
/* generic poll functions */
|
||||
bool rna_Lattice_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
|
||||
{
|
||||
|
@ -2486,52 +2335,6 @@ static void rna_def_vertex_group(BlenderRNA *brna)
|
|||
RNA_def_function_return(func, parm);
|
||||
}
|
||||
|
||||
static void rna_def_face_map(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
srna = RNA_def_struct(brna, "FaceMap", NULL);
|
||||
RNA_def_struct_sdna(srna, "bFaceMap");
|
||||
RNA_def_struct_ui_text(
|
||||
srna, "Face Map", "Group of faces, each face can only be part of one map");
|
||||
RNA_def_struct_ui_icon(srna, ICON_MOD_TRIANGULATE);
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Name", "Face map name");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_FaceMap_name_set");
|
||||
/* update data because modifiers may use #24761. */
|
||||
RNA_def_property_update(prop, NC_GEOM | ND_DATA | NA_RENAME, "rna_Object_internal_update_data");
|
||||
|
||||
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
|
||||
RNA_def_property_ui_text(prop, "Select", "Face map selection state (for tools to use)");
|
||||
/* important not to use a notifier here, creates a feedback loop! */
|
||||
|
||||
prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_int_funcs(prop, "rna_FaceMap_index_get", NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Index", "Index number of the face map");
|
||||
|
||||
func = RNA_def_function(srna, "add", "rna_FaceMap_face_add");
|
||||
RNA_def_function_ui_description(func, "Add faces to the face-map");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
|
||||
/* TODO: see how array size of 0 works, this shouldn't be used. */
|
||||
parm = RNA_def_int_array(func, "index", 1, NULL, 0, 0, "", "List of indices", 0, 0);
|
||||
RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
|
||||
|
||||
func = RNA_def_function(srna, "remove", "rna_FaceMap_face_remove");
|
||||
RNA_def_function_ui_description(func, "Remove faces from the face-map");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
|
||||
/* TODO: see how array size of 0 works, this shouldn't be used. */
|
||||
parm = RNA_def_int_array(func, "index", 1, NULL, 0, 0, "", "List of indices", 0, 0);
|
||||
RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
|
||||
}
|
||||
|
||||
static void rna_def_material_slot(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
@ -2921,56 +2724,6 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
|
|||
RNA_def_function_ui_description(func, "Delete all vertex groups from object");
|
||||
}
|
||||
|
||||
/* object.face_maps */
|
||||
static void rna_def_object_face_maps(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
PropertyRNA *prop;
|
||||
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
RNA_def_property_srna(cprop, "FaceMaps");
|
||||
srna = RNA_def_struct(brna, "FaceMaps", NULL);
|
||||
RNA_def_struct_sdna(srna, "Object");
|
||||
RNA_def_struct_ui_text(srna, "Face Maps", "Collection of face maps");
|
||||
|
||||
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "FaceMap");
|
||||
RNA_def_property_pointer_funcs(
|
||||
prop, "rna_Object_active_face_map_get", "rna_Object_active_face_map_set", NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Active Face Map", "Face maps of the object");
|
||||
RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data");
|
||||
|
||||
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "actfmap");
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_Object_active_face_map_index_get",
|
||||
"rna_Object_active_face_map_index_set",
|
||||
"rna_Object_active_face_map_index_range");
|
||||
RNA_def_property_ui_text(prop, "Active Face Map Index", "Active index in face map array");
|
||||
RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data");
|
||||
|
||||
/* face maps */ /* add_face_map */
|
||||
func = RNA_def_function(srna, "new", "rna_Object_fmap_new");
|
||||
RNA_def_function_ui_description(func, "Add face map to object");
|
||||
RNA_def_string(func, "name", "Map", 0, "", "face map name"); /* optional */
|
||||
parm = RNA_def_pointer(func, "fmap", "FaceMap", "", "New face map");
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
func = RNA_def_function(srna, "remove", "rna_Object_fmap_remove");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
RNA_def_function_ui_description(func, "Delete vertex group from object");
|
||||
parm = RNA_def_pointer(func, "group", "FaceMap", "", "Face map to remove");
|
||||
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
|
||||
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
|
||||
|
||||
func = RNA_def_function(srna, "clear", "rna_Object_fmap_clear");
|
||||
RNA_def_function_ui_description(func, "Delete all vertex groups from object");
|
||||
}
|
||||
|
||||
static void rna_def_object_display(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
@ -3599,14 +3352,6 @@ static void rna_def_object(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Vertex Groups", "Vertex groups of the object");
|
||||
rna_def_object_vertex_groups(brna, prop);
|
||||
|
||||
/* face maps */
|
||||
prop = RNA_def_property(srna, "face_maps", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "fmaps", NULL);
|
||||
RNA_def_property_struct_type(prop, "FaceMap");
|
||||
RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(prop, "Face Maps", "Maps of faces of the object");
|
||||
rna_def_object_face_maps(brna, prop);
|
||||
|
||||
/* empty */
|
||||
prop = RNA_def_property(srna, "empty_display_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "empty_drawtype");
|
||||
|
@ -4017,7 +3762,6 @@ void RNA_def_object(BlenderRNA *brna)
|
|||
|
||||
RNA_define_animate_sdna(false);
|
||||
rna_def_vertex_group(brna);
|
||||
rna_def_face_map(brna);
|
||||
rna_def_material_slot(brna);
|
||||
rna_def_object_display(brna);
|
||||
rna_def_object_lineart(brna);
|
||||
|
|
|
@ -44,12 +44,6 @@ static void rna_gizmo_draw_preset_circle(wmGizmo *gz, float matrix[16], int axis
|
|||
ED_gizmo_draw_preset_circle(gz, (float(*)[4])matrix, axis, select_id);
|
||||
}
|
||||
|
||||
static void rna_gizmo_draw_preset_facemap(
|
||||
wmGizmo *gz, struct bContext *C, struct Object *ob, int facemap, int select_id)
|
||||
{
|
||||
ED_gizmo_draw_preset_facemap(C, gz, ob, facemap, select_id);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Gizmo Property Define
|
||||
* \{ */
|
||||
|
@ -261,24 +255,6 @@ void RNA_api_gizmo(StructRNA *srna)
|
|||
/* -------------------------------------------------------------------- */
|
||||
/* Other Shapes */
|
||||
|
||||
/* draw_preset_facemap */
|
||||
func = RNA_def_function(srna, "draw_preset_facemap", "rna_gizmo_draw_preset_facemap");
|
||||
RNA_def_function_ui_description(func, "Draw the face-map of a mesh object");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
parm = RNA_def_pointer(func, "object", "Object", "", "Object");
|
||||
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
|
||||
parm = RNA_def_int(func, "face_map", 0, 0, INT_MAX, "Face map index", "", 0, INT_MAX);
|
||||
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||
RNA_def_int(func,
|
||||
"select_id",
|
||||
-1,
|
||||
-1,
|
||||
INT_MAX,
|
||||
"ID to use when gizmo is selectable. Use -1 when not selecting",
|
||||
"",
|
||||
-1,
|
||||
INT_MAX);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Property API */
|
||||
|
||||
|
|
|
@ -825,36 +825,47 @@ class RenderLayerOperation : public NodeOperation {
|
|||
void execute() override
|
||||
{
|
||||
const int view_layer = bnode().custom1;
|
||||
GPUTexture *pass_texture = context().get_input_texture(view_layer, RE_PASSNAME_COMBINED);
|
||||
GPUTexture *combined_texture = context().get_input_texture(view_layer, RE_PASSNAME_COMBINED);
|
||||
|
||||
execute_image(pass_texture);
|
||||
execute_alpha(pass_texture);
|
||||
execute_pass("Image", combined_texture, "compositor_read_pass_color");
|
||||
execute_pass("Alpha", combined_texture, "compositor_read_pass_alpha");
|
||||
|
||||
/* Other output passes are not supported for now, so allocate them as invalid. */
|
||||
for (const bNodeSocket *output : this->node()->output_sockets()) {
|
||||
if (!STR_ELEM(output->identifier, "Image", "Alpha")) {
|
||||
Result &unsupported_result = get_result(output->identifier);
|
||||
if (unsupported_result.should_compute()) {
|
||||
unsupported_result.allocate_invalid();
|
||||
context().set_info_message("Viewport compositor setup not fully supported");
|
||||
}
|
||||
if (STR_ELEM(output->identifier, "Image", "Alpha")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GPUTexture *pass_texture = context().get_input_texture(view_layer, output->identifier);
|
||||
if (output->type == SOCK_FLOAT) {
|
||||
execute_pass(output->identifier, pass_texture, "compositor_read_pass_float");
|
||||
}
|
||||
else if (output->type == SOCK_VECTOR) {
|
||||
execute_pass(output->identifier, pass_texture, "compositor_read_pass_vector");
|
||||
}
|
||||
else if (output->type == SOCK_RGBA) {
|
||||
execute_pass(output->identifier, pass_texture, "compositor_read_pass_color");
|
||||
}
|
||||
else {
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void execute_image(GPUTexture *pass_texture)
|
||||
void execute_pass(const char *pass_name, GPUTexture *pass_texture, const char *shader_name)
|
||||
{
|
||||
Result &image_result = get_result("Image");
|
||||
Result &image_result = get_result(pass_name);
|
||||
if (!image_result.should_compute()) {
|
||||
return;
|
||||
}
|
||||
if (pass_texture == nullptr) {
|
||||
/* Pass not rendered (yet). */
|
||||
/* Pass not rendered yet, or not supported by viewport. */
|
||||
image_result.allocate_invalid();
|
||||
context().set_info_message("Viewport compositor setup not fully supported");
|
||||
return;
|
||||
}
|
||||
|
||||
GPUShader *shader = shader_manager().get("compositor_read_pass");
|
||||
GPUShader *shader = shader_manager().get(shader_name);
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
/* The compositing space might be limited to a subset of the pass texture, so only read that
|
||||
|
@ -876,41 +887,6 @@ class RenderLayerOperation : public NodeOperation {
|
|||
GPU_texture_unbind(pass_texture);
|
||||
image_result.unbind_as_image();
|
||||
}
|
||||
|
||||
void execute_alpha(GPUTexture *pass_texture)
|
||||
{
|
||||
Result &alpha_result = get_result("Alpha");
|
||||
if (!alpha_result.should_compute()) {
|
||||
return;
|
||||
}
|
||||
if (pass_texture == nullptr) {
|
||||
/* Pass not rendered (yet). */
|
||||
alpha_result.allocate_invalid();
|
||||
return;
|
||||
}
|
||||
|
||||
GPUShader *shader = shader_manager().get("compositor_read_pass_alpha");
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
/* The compositing space might be limited to a subset of the pass texture, so only read that
|
||||
* compositing region into an appropriately sized texture. */
|
||||
const rcti compositing_region = context().get_compositing_region();
|
||||
const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin);
|
||||
GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound);
|
||||
|
||||
const int input_unit = GPU_shader_get_sampler_binding(shader, "input_tx");
|
||||
GPU_texture_bind(pass_texture, input_unit);
|
||||
|
||||
const int2 compositing_region_size = context().get_compositing_region_size();
|
||||
alpha_result.allocate_texture(Domain(compositing_region_size));
|
||||
alpha_result.bind_as_image(shader, "output_img");
|
||||
|
||||
compute_dispatch_threads_at_least(shader, compositing_region_size);
|
||||
|
||||
GPU_shader_unbind();
|
||||
GPU_texture_unbind(pass_texture);
|
||||
alpha_result.unbind_as_image();
|
||||
}
|
||||
};
|
||||
|
||||
static NodeOperation *get_compositor_operation(Context &context, DNode node)
|
||||
|
|
|
@ -77,7 +77,7 @@ class ViewerOperation : public NodeOperation {
|
|||
const Result &second_image = get_input("Image_001");
|
||||
second_image.bind_as_texture(shader, "second_image_tx");
|
||||
|
||||
GPUTexture *output_texture = context().get_output_texture();
|
||||
GPUTexture *output_texture = context().get_viewer_output_texture();
|
||||
const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img");
|
||||
GPU_texture_image_bind(output_texture, image_unit);
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ class ViewerOperation : public NodeOperation {
|
|||
color.w = alpha.get_float_value();
|
||||
}
|
||||
|
||||
GPU_texture_clear(context().get_output_texture(), GPU_DATA_FLOAT, color);
|
||||
GPU_texture_clear(context().get_viewer_output_texture(), GPU_DATA_FLOAT, color);
|
||||
}
|
||||
|
||||
/* Executes when the alpha channel of the image is ignored. */
|
||||
|
@ -123,7 +123,7 @@ class ViewerOperation : public NodeOperation {
|
|||
const Result &image = get_input("Image");
|
||||
image.bind_as_texture(shader, "input_tx");
|
||||
|
||||
GPUTexture *output_texture = context().get_output_texture();
|
||||
GPUTexture *output_texture = context().get_viewer_output_texture();
|
||||
const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img");
|
||||
GPU_texture_image_bind(output_texture, image_unit);
|
||||
|
||||
|
@ -151,7 +151,7 @@ class ViewerOperation : public NodeOperation {
|
|||
const Result &image = get_input("Image");
|
||||
image.bind_as_texture(shader, "input_tx");
|
||||
|
||||
GPUTexture *output_texture = context().get_output_texture();
|
||||
GPUTexture *output_texture = context().get_viewer_output_texture();
|
||||
const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img");
|
||||
GPU_texture_image_bind(output_texture, image_unit);
|
||||
|
||||
|
@ -181,7 +181,7 @@ class ViewerOperation : public NodeOperation {
|
|||
const Result &alpha = get_input("Alpha");
|
||||
alpha.bind_as_texture(shader, "alpha_tx");
|
||||
|
||||
GPUTexture *output_texture = context().get_output_texture();
|
||||
GPUTexture *output_texture = context().get_viewer_output_texture();
|
||||
const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img");
|
||||
GPU_texture_image_bind(output_texture, image_unit);
|
||||
|
||||
|
|
|
@ -127,7 +127,6 @@ static void expand_mesh(Mesh &mesh,
|
|||
CustomData_realloc(&mesh.edata, old_edges_num, mesh.totedge);
|
||||
}
|
||||
if (poly_expand != 0) {
|
||||
CustomData_free_layers(&mesh.pdata, CD_FACEMAP, mesh.totpoly);
|
||||
CustomData_free_layers(&mesh.pdata, CD_FREESTYLE_FACE, mesh.totpoly);
|
||||
const int old_polys_num = mesh.totpoly;
|
||||
mesh.totpoly += poly_expand;
|
||||
|
|
|
@ -98,8 +98,6 @@ PyDoc_STRVAR(bpy_bmlayeraccess_collection__skin_doc,
|
|||
"Accessor for skin layer.\n\ntype: :class:`BMLayerCollection`");
|
||||
PyDoc_STRVAR(bpy_bmlayeraccess_collection__paint_mask_doc,
|
||||
"Accessor for paint mask layer.\n\ntype: :class:`BMLayerCollection`");
|
||||
PyDoc_STRVAR(bpy_bmlayeraccess_collection__face_map_doc,
|
||||
"FaceMap custom-data layer.\n\ntype: :class:`BMLayerCollection`");
|
||||
#ifdef WITH_FREESTYLE
|
||||
PyDoc_STRVAR(bpy_bmlayeraccess_collection__freestyle_edge_doc,
|
||||
"Accessor for Freestyle edge layer.\n\ntype: :class:`BMLayerCollection`");
|
||||
|
@ -302,11 +300,6 @@ static PyGetSetDef bpy_bmlayeraccess_face_getseters[] = {
|
|||
(setter)NULL,
|
||||
bpy_bmlayeraccess_collection__string_doc,
|
||||
(void *)CD_PROP_STRING},
|
||||
{"face_map",
|
||||
(getter)bpy_bmlayeraccess_collection_get,
|
||||
(setter)NULL,
|
||||
bpy_bmlayeraccess_collection__face_map_doc,
|
||||
(void *)CD_FACEMAP},
|
||||
|
||||
#ifdef WITH_FREESTYLE
|
||||
{"freestyle",
|
||||
|
@ -1115,8 +1108,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
|
|||
ret = PyFloat_FromDouble(*(float *)value);
|
||||
break;
|
||||
}
|
||||
case CD_PROP_INT32:
|
||||
case CD_FACEMAP: {
|
||||
case CD_PROP_INT32: {
|
||||
ret = PyLong_FromLong(*(int *)value);
|
||||
break;
|
||||
}
|
||||
|
@ -1194,8 +1186,7 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CD_PROP_INT32:
|
||||
case CD_FACEMAP: {
|
||||
case CD_PROP_INT32: {
|
||||
const int tmp_val = PyC_Long_AsI32(py_value);
|
||||
if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
|
||||
/* error is set */
|
||||
|
|
|
@ -2,9 +2,13 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_node.hh"
|
||||
|
@ -12,6 +16,9 @@
|
|||
|
||||
#include "DRW_engine.h"
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "COM_context.hh"
|
||||
#include "COM_evaluator.hh"
|
||||
|
||||
|
@ -63,6 +70,9 @@ class Context : public realtime_compositor::Context {
|
|||
/* Output combined texture. */
|
||||
GPUTexture *output_texture_ = nullptr;
|
||||
|
||||
/* Viewer output texture. */
|
||||
GPUTexture *viewer_output_texture_ = nullptr;
|
||||
|
||||
public:
|
||||
Context(const Scene &scene,
|
||||
const RenderData &render_data,
|
||||
|
@ -81,7 +91,8 @@ class Context : public realtime_compositor::Context {
|
|||
|
||||
virtual ~Context()
|
||||
{
|
||||
GPU_texture_free(output_texture_);
|
||||
GPU_TEXTURE_FREE_SAFE(output_texture_);
|
||||
GPU_TEXTURE_FREE_SAFE(viewer_output_texture_);
|
||||
}
|
||||
|
||||
const bNodeTree &get_node_tree() const override
|
||||
|
@ -94,6 +105,11 @@ class Context : public realtime_compositor::Context {
|
|||
return use_file_output_;
|
||||
}
|
||||
|
||||
bool use_composite_output() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool use_texture_color_management() const override
|
||||
{
|
||||
return BKE_scene_check_color_management_enabled(&scene_);
|
||||
|
@ -121,7 +137,7 @@ class Context : public realtime_compositor::Context {
|
|||
|
||||
GPUTexture *get_output_texture() override
|
||||
{
|
||||
/* TODO: support outputting for viewers and previews.
|
||||
/* TODO: support outputting for previews.
|
||||
* TODO: just a temporary hack, needs to get stored in RenderResult,
|
||||
* once that supports GPU buffers. */
|
||||
if (output_texture_ == nullptr) {
|
||||
|
@ -138,6 +154,25 @@ class Context : public realtime_compositor::Context {
|
|||
return output_texture_;
|
||||
}
|
||||
|
||||
GPUTexture *get_viewer_output_texture() override
|
||||
{
|
||||
/* TODO: support outputting previews.
|
||||
* TODO: just a temporary hack, needs to get stored in RenderResult,
|
||||
* once that supports GPU buffers. */
|
||||
if (viewer_output_texture_ == nullptr) {
|
||||
const int2 size = get_render_size();
|
||||
viewer_output_texture_ = GPU_texture_create_2d("compositor_viewer_output_texture",
|
||||
size.x,
|
||||
size.y,
|
||||
1,
|
||||
GPU_RGBA16F,
|
||||
GPU_TEXTURE_USAGE_GENERAL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return viewer_output_texture_;
|
||||
}
|
||||
|
||||
GPUTexture *get_input_texture(int view_layer_id, const char *pass_name) override
|
||||
{
|
||||
/* TODO: eventually this should get cached on the RenderResult itself when
|
||||
|
@ -224,6 +259,10 @@ class Context : public realtime_compositor::Context {
|
|||
|
||||
void output_to_render_result()
|
||||
{
|
||||
if (!output_texture_) {
|
||||
return;
|
||||
}
|
||||
|
||||
Render *re = RE_GetSceneRender(&scene_);
|
||||
RenderResult *rr = RE_AcquireResultWrite(re);
|
||||
|
||||
|
@ -253,6 +292,55 @@ class Context : public realtime_compositor::Context {
|
|||
BKE_image_signal(G.main, image, nullptr, IMA_SIGNAL_FREE);
|
||||
BLI_thread_unlock(LOCK_DRAW_IMAGE);
|
||||
}
|
||||
|
||||
void viewer_output_to_viewer_image()
|
||||
{
|
||||
if (!viewer_output_texture_) {
|
||||
return;
|
||||
}
|
||||
|
||||
Image *image = BKE_image_ensure_viewer(G.main, IMA_TYPE_COMPOSITE, "Viewer Node");
|
||||
|
||||
ImageUser image_user = {0};
|
||||
image_user.multi_index = BKE_scene_multiview_view_id_get(&render_data_, view_name_);
|
||||
|
||||
if (BKE_scene_multiview_is_render_view_first(&render_data_, view_name_)) {
|
||||
BKE_image_ensure_viewer_views(&render_data_, image, &image_user);
|
||||
}
|
||||
|
||||
BLI_thread_lock(LOCK_DRAW_IMAGE);
|
||||
|
||||
void *lock;
|
||||
ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &image_user, &lock);
|
||||
|
||||
const int2 render_size = get_render_size();
|
||||
if (image_buffer->x != render_size.x || image_buffer->y != render_size.y) {
|
||||
imb_freerectImBuf(image_buffer);
|
||||
imb_freerectfloatImBuf(image_buffer);
|
||||
IMB_freezbuffloatImBuf(image_buffer);
|
||||
image_buffer->x = render_size.x;
|
||||
image_buffer->y = render_size.y;
|
||||
imb_addrectfloatImBuf(image_buffer, 4);
|
||||
image_buffer->userflags |= IB_DISPLAY_BUFFER_INVALID;
|
||||
}
|
||||
|
||||
BKE_image_release_ibuf(image, image_buffer, lock);
|
||||
BLI_thread_unlock(LOCK_DRAW_IMAGE);
|
||||
|
||||
GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE);
|
||||
float *output_buffer = (float *)GPU_texture_read(viewer_output_texture_, GPU_DATA_FLOAT, 0);
|
||||
|
||||
std::memcpy(image_buffer->float_buffer.data,
|
||||
output_buffer,
|
||||
render_size.x * render_size.y * 4 * sizeof(float));
|
||||
|
||||
MEM_freeN(output_buffer);
|
||||
|
||||
BKE_image_partial_update_mark_full_update(image);
|
||||
if (node_tree_.runtime->update_draw) {
|
||||
node_tree_.runtime->update_draw(node_tree_.runtime->udh);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Render Realtime Compositor */
|
||||
|
@ -289,6 +377,7 @@ void RealtimeCompositor::execute()
|
|||
DRW_render_context_enable(&render_);
|
||||
evaluator_->evaluate();
|
||||
context_->output_to_render_result();
|
||||
context_->viewer_output_to_viewer_image();
|
||||
DRW_render_context_disable(&render_);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct ARegion;
|
||||
struct AssetHandle;
|
||||
struct GHashIterator;
|
||||
struct GPUViewport;
|
||||
struct ID;
|
||||
|
@ -1444,8 +1443,7 @@ bool WM_drag_is_ID_type(const struct wmDrag *drag, int idcode);
|
|||
/**
|
||||
* \note Does not store \a asset in any way, so it's fine to pass a temporary.
|
||||
*/
|
||||
wmDragAsset *WM_drag_create_asset_data(const struct AssetHandle *asset,
|
||||
const char *path,
|
||||
wmDragAsset *WM_drag_create_asset_data(const struct AssetRepresentation *asset,
|
||||
int /* #eAssetImportMethod */ import_type);
|
||||
struct wmDragAsset *WM_drag_get_asset_data(const struct wmDrag *drag, int idcode);
|
||||
struct AssetMetaData *WM_drag_get_asset_meta_data(const struct wmDrag *drag, int idcode);
|
||||
|
@ -1475,7 +1473,7 @@ struct wmDragAssetCatalog *WM_drag_get_asset_catalog_data(const struct wmDrag *d
|
|||
/**
|
||||
* \note Does not store \a asset in any way, so it's fine to pass a temporary.
|
||||
*/
|
||||
void WM_drag_add_asset_list_item(wmDrag *drag, const struct AssetHandle *asset);
|
||||
void WM_drag_add_asset_list_item(wmDrag *drag, const struct AssetRepresentation *asset);
|
||||
const ListBase *WM_drag_asset_list_get(const wmDrag *drag);
|
||||
|
||||
const char *WM_drag_get_item_name(struct wmDrag *drag);
|
||||
|
|
|
@ -1095,16 +1095,8 @@ typedef struct wmDragID {
|
|||
} wmDragID;
|
||||
|
||||
typedef struct wmDragAsset {
|
||||
/* NOTE: Can't store the #AssetHandle here, since the #FileDirEntry it wraps may be freed while
|
||||
* dragging. So store necessary data here directly. */
|
||||
|
||||
char name[64]; /* MAX_NAME */
|
||||
/* Always freed. */
|
||||
const char *path;
|
||||
int id_type;
|
||||
struct AssetMetaData *metadata;
|
||||
int import_method; /* eAssetImportType */
|
||||
bool use_relative_path;
|
||||
const struct AssetRepresentation *asset;
|
||||
|
||||
/* FIXME: This is temporary evil solution to get scene/view-layer/etc in the copy callback of the
|
||||
* #wmDropBox.
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
|
||||
#include <cstring>
|
||||
|
||||
#include "AS_asset_representation.h"
|
||||
#include "AS_asset_representation.hh"
|
||||
|
||||
#include "DNA_asset_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
@ -212,7 +215,7 @@ wmDrag *WM_drag_data_create(
|
|||
LISTBASE_FOREACH (const CollectionPointerLink *, link, &asset_file_links) {
|
||||
const FileDirEntry *asset_file = static_cast<const FileDirEntry *>(link->ptr.data);
|
||||
const AssetHandle asset_handle = {asset_file};
|
||||
WM_drag_add_asset_list_item(drag, &asset_handle);
|
||||
WM_drag_add_asset_list_item(drag, ED_asset_handle_get_representation(&asset_handle));
|
||||
}
|
||||
BLI_freelistN(&asset_file_links);
|
||||
break;
|
||||
|
@ -566,23 +569,18 @@ bool WM_drag_is_ID_type(const wmDrag *drag, int idcode)
|
|||
return WM_drag_get_local_ID(drag, idcode) || WM_drag_get_asset_data(drag, idcode);
|
||||
}
|
||||
|
||||
wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset, const char *path, int import_type)
|
||||
wmDragAsset *WM_drag_create_asset_data(const AssetRepresentation *asset, int import_type)
|
||||
{
|
||||
wmDragAsset *asset_drag = MEM_new<wmDragAsset>(__func__);
|
||||
|
||||
STRNCPY(asset_drag->name, ED_asset_handle_get_name(asset));
|
||||
asset_drag->metadata = ED_asset_handle_get_metadata(asset);
|
||||
asset_drag->path = path;
|
||||
asset_drag->id_type = ED_asset_handle_get_id_type(asset);
|
||||
asset_drag->asset = asset;
|
||||
asset_drag->import_method = import_type;
|
||||
asset_drag->use_relative_path = ED_asset_handle_get_use_relative_path(asset);
|
||||
|
||||
return asset_drag;
|
||||
}
|
||||
|
||||
static void wm_drag_free_asset_data(wmDragAsset **asset_data)
|
||||
{
|
||||
MEM_freeN((char *)(*asset_data)->path);
|
||||
MEM_SAFE_FREE(*asset_data);
|
||||
}
|
||||
|
||||
|
@ -593,14 +591,15 @@ wmDragAsset *WM_drag_get_asset_data(const wmDrag *drag, int idcode)
|
|||
}
|
||||
|
||||
wmDragAsset *asset_drag = static_cast<wmDragAsset *>(drag->poin);
|
||||
return ELEM(idcode, 0, asset_drag->id_type) ? asset_drag : nullptr;
|
||||
ID_Type asset_idcode = AS_asset_representation_id_type_get(asset_drag->asset);
|
||||
return ELEM(idcode, 0, asset_idcode) ? asset_drag : nullptr;
|
||||
}
|
||||
|
||||
AssetMetaData *WM_drag_get_asset_meta_data(const wmDrag *drag, int idcode)
|
||||
{
|
||||
wmDragAsset *drag_asset = WM_drag_get_asset_data(drag, idcode);
|
||||
if (drag_asset) {
|
||||
return drag_asset->metadata;
|
||||
return AS_asset_representation_metadata_get(drag_asset->asset);
|
||||
}
|
||||
|
||||
ID *local_id = WM_drag_get_local_ID(drag, idcode);
|
||||
|
@ -618,8 +617,10 @@ ID *WM_drag_asset_id_import(wmDragAsset *asset_drag, const int flag_extra)
|
|||
eFileSel_Params_Flag flag = static_cast<eFileSel_Params_Flag>(flag_extra) |
|
||||
FILE_ACTIVE_COLLECTION;
|
||||
|
||||
const char *name = asset_drag->name;
|
||||
ID_Type idtype = static_cast<ID_Type>(asset_drag->id_type);
|
||||
const char *name = AS_asset_representation_name_get(asset_drag->asset);
|
||||
const std::string blend_path = AS_asset_representation_full_library_path_get(asset_drag->asset);
|
||||
const ID_Type idtype = AS_asset_representation_id_type_get(asset_drag->asset);
|
||||
const bool use_relative_path = AS_asset_representation_use_relative_path_get(asset_drag->asset);
|
||||
|
||||
/* FIXME: Link/Append should happens in the operator called at the end of drop process, not from
|
||||
* here. */
|
||||
|
@ -629,15 +630,13 @@ ID *WM_drag_asset_id_import(wmDragAsset *asset_drag, const int flag_extra)
|
|||
ViewLayer *view_layer = CTX_data_view_layer(asset_drag->evil_C);
|
||||
View3D *view3d = CTX_wm_view3d(asset_drag->evil_C);
|
||||
|
||||
const bool use_relative_path = asset_drag->use_relative_path;
|
||||
|
||||
switch (eAssetImportMethod(asset_drag->import_method)) {
|
||||
case ASSET_IMPORT_LINK:
|
||||
return WM_file_link_datablock(bmain,
|
||||
scene,
|
||||
view_layer,
|
||||
view3d,
|
||||
asset_drag->path,
|
||||
blend_path.c_str(),
|
||||
idtype,
|
||||
name,
|
||||
flag | (use_relative_path ? FILE_RELPATH : 0));
|
||||
|
@ -646,7 +645,7 @@ ID *WM_drag_asset_id_import(wmDragAsset *asset_drag, const int flag_extra)
|
|||
scene,
|
||||
view_layer,
|
||||
view3d,
|
||||
asset_drag->path,
|
||||
blend_path.c_str(),
|
||||
idtype,
|
||||
name,
|
||||
flag | BLO_LIBLINK_APPEND_RECURSIVE |
|
||||
|
@ -657,7 +656,7 @@ ID *WM_drag_asset_id_import(wmDragAsset *asset_drag, const int flag_extra)
|
|||
scene,
|
||||
view_layer,
|
||||
view3d,
|
||||
asset_drag->path,
|
||||
blend_path.c_str(),
|
||||
idtype,
|
||||
name,
|
||||
flag | BLO_LIBLINK_APPEND_RECURSIVE | BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR |
|
||||
|
@ -708,10 +707,11 @@ void WM_drag_free_imported_drag_ID(Main *bmain, wmDrag *drag, wmDropBox *drop)
|
|||
return;
|
||||
}
|
||||
|
||||
ID_Type asset_id_type = AS_asset_representation_id_type_get(asset_drag->asset);
|
||||
/* Try to find the imported ID. For this to work either a "session_uuid" or "name" property must
|
||||
* have been defined (see #WM_operator_properties_id_lookup()). */
|
||||
ID *id = WM_operator_properties_id_lookup_from_name_or_session_uuid(
|
||||
bmain, drop->ptr, static_cast<ID_Type>(asset_drag->id_type));
|
||||
bmain, drop->ptr, asset_id_type);
|
||||
if (id != nullptr) {
|
||||
/* Do not delete the dragged ID if it has any user, otherwise if it is a 're-used' ID it will
|
||||
* cause #95636. Note that we need first to add the user that we want to remove in
|
||||
|
@ -730,7 +730,7 @@ wmDragAssetCatalog *WM_drag_get_asset_catalog_data(const wmDrag *drag)
|
|||
return static_cast<wmDragAssetCatalog *>(drag->poin);
|
||||
}
|
||||
|
||||
void WM_drag_add_asset_list_item(wmDrag *drag, const AssetHandle *asset)
|
||||
void WM_drag_add_asset_list_item(wmDrag *drag, const AssetRepresentation *asset)
|
||||
{
|
||||
BLI_assert(drag->type == WM_DRAG_ASSET_LIST);
|
||||
|
||||
|
@ -738,17 +738,14 @@ void WM_drag_add_asset_list_item(wmDrag *drag, const AssetHandle *asset)
|
|||
|
||||
/* Add to list. */
|
||||
wmDragAssetListItem *drag_asset = MEM_cnew<wmDragAssetListItem>(__func__);
|
||||
ID *local_id = ED_asset_handle_get_local_id(asset);
|
||||
ID *local_id = AS_asset_representation_local_id_get(asset);
|
||||
if (local_id) {
|
||||
drag_asset->is_external = false;
|
||||
drag_asset->asset_data.local_id = local_id;
|
||||
}
|
||||
else {
|
||||
char asset_blend_path[FILE_MAX_LIBEXTRA];
|
||||
ED_asset_handle_get_full_library_path(asset, asset_blend_path);
|
||||
drag_asset->is_external = true;
|
||||
drag_asset->asset_data.external_info = WM_drag_create_asset_data(
|
||||
asset, BLI_strdup(asset_blend_path), ASSET_IMPORT_APPEND);
|
||||
drag_asset->asset_data.external_info = WM_drag_create_asset_data(asset, ASSET_IMPORT_APPEND);
|
||||
}
|
||||
BLI_addtail(&drag->asset_items, drag_asset);
|
||||
}
|
||||
|
@ -844,7 +841,7 @@ const char *WM_drag_get_item_name(wmDrag *drag)
|
|||
}
|
||||
case WM_DRAG_ASSET: {
|
||||
const wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, 0);
|
||||
return asset_drag->name;
|
||||
return AS_asset_representation_name_get(asset_drag->asset);
|
||||
}
|
||||
case WM_DRAG_PATH: {
|
||||
const wmDragPath *path_drag_data = static_cast<const wmDragPath *>(drag->poin);
|
||||
|
|
Loading…
Reference in New Issue