Geometry Nodes: add simulation support #104924

Closed
Hans Goudey wants to merge 211 commits from geometry-nodes-simulation into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
142 changed files with 947 additions and 778 deletions
Showing only changes of commit 945d71b56b - Show all commits

View File

@ -521,7 +521,8 @@ endif()
if(NOT APPLE)
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON)
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
set(CYCLES_HIP_BINARIES_ARCH gfx900 gfx906 gfx90c gfx902 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
# Radeon VII (gfx906) not currently working with HIP SDK, so left out of the list.
set(CYCLES_HIP_BINARIES_ARCH gfx900 gfx90c gfx902 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
endif()

View File

@ -113,8 +113,14 @@ add_dependencies(
if(BUILD_MODE STREQUAL Release AND WIN32)
ExternalProject_Add_Step(external_dpcpp after_install
COMMAND ${CMAKE_COMMAND} -E rm -f ${LIBDIR}/dpcpp/bin/clang-cl.exe
COMMAND ${CMAKE_COMMAND} -E rm -f ${LIBDIR}/dpcpp/bin/clang-cpp.exe
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/dpcpp ${HARVEST_TARGET}/dpcpp
COMMAND ${CMAKE_COMMAND} -E rm -f ${HARVEST_TARGET}/dpcpp/bin/clang-cl.exe
COMMAND ${CMAKE_COMMAND} -E rm -f ${HARVEST_TARGET}/dpcpp/bin/clang-cpp.exe
COMMAND ${CMAKE_COMMAND} -E rm -f ${HARVEST_TARGET}/dpcpp/bin/clang.exe
COMMAND ${CMAKE_COMMAND} -E rm -f ${HARVEST_TARGET}/dpcpp/bin/ld.lld.exe
COMMAND ${CMAKE_COMMAND} -E rm -f ${HARVEST_TARGET}/dpcpp/bin/ld64.lld.exe
COMMAND ${CMAKE_COMMAND} -E rm -f ${HARVEST_TARGET}/dpcpp/bin/lld.exe
COMMAND ${CMAKE_COMMAND} -E rm -f ${HARVEST_TARGET}/dpcpp/bin/lld-link.exe
COMMAND ${CMAKE_COMMAND} -E rm -f ${HARVEST_TARGET}/dpcpp/bin/wasm-ld.exe
)
endif()

View File

@ -37,18 +37,24 @@ elseif(HIP_HIPCC_EXECUTABLE)
set(HIP_VERSION_MINOR 0)
set(HIP_VERSION_PATCH 0)
if(WIN32)
set(_hipcc_executable ${HIP_HIPCC_EXECUTABLE}.bat)
else()
set(_hipcc_executable ${HIP_HIPCC_EXECUTABLE})
endif()
# Get version from the output.
execute_process(COMMAND ${HIP_HIPCC_EXECUTABLE} --version
OUTPUT_VARIABLE HIP_VERSION_RAW
execute_process(COMMAND ${_hipcc_executable} --version
OUTPUT_VARIABLE _hip_version_raw
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Parse parts.
if(HIP_VERSION_RAW MATCHES "HIP version: .*")
if(_hip_version_raw MATCHES "HIP version: .*")
# Strip the HIP prefix and get list of individual version components.
string(REGEX REPLACE
".*HIP version: ([.0-9]+).*" "\\1"
HIP_SEMANTIC_VERSION "${HIP_VERSION_RAW}")
HIP_SEMANTIC_VERSION "${_hip_version_raw}")
string(REPLACE "." ";" HIP_VERSION_PARTS "${HIP_SEMANTIC_VERSION}")
list(LENGTH HIP_VERSION_PARTS NUM_HIP_VERSION_PARTS)
@ -71,7 +77,13 @@ elseif(HIP_HIPCC_EXECUTABLE)
# Construct full semantic version.
set(HIP_VERSION "${HIP_VERSION_MAJOR}.${HIP_VERSION_MINOR}.${HIP_VERSION_PATCH}")
unset(HIP_VERSION_RAW)
unset(_hip_version_raw)
unset(_hipcc_executable)
else()
set(HIP_FOUND FALSE)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(HIP
REQUIRED_VARS HIP_HIPCC_EXECUTABLE
VERSION_VAR HIP_VERSION)

View File

@ -82,7 +82,7 @@ if(NOT APPLE)
set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_CUBIN_COMPILER OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_HIP_BINARIES OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_HIP_BINARIES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_DEVICE_ONEAPI ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_ONEAPI_BINARIES ON CACHE BOOL "" FORCE)
endif()

View File

@ -9,7 +9,7 @@ buildbot:
cuda11:
version: '11.4.1'
hip:
version: '5.3.22480'
version: '5.5.30571'
optix:
version: '7.3.0'
ocloc:

View File

@ -1683,16 +1683,16 @@ class CyclesPreferences(bpy.types.AddonPreferences):
col.label(text=iface_("and NVIDIA driver version %s or newer") % driver_version,
icon='BLANK1', translate=False)
elif device_type == 'HIP':
if True:
col.label(text="HIP temporarily disabled due to compiler bugs", icon='BLANK1')
else:
import sys
if sys.platform[:3] == "win":
driver_version = "21.Q4"
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
col.label(text=iface_("and AMD Radeon Pro %s driver or newer") % driver_version,
icon='BLANK1', translate=False)
elif sys.platform.startswith("linux"):
import sys
if sys.platform[:3] == "win":
driver_version = "21.Q4"
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
col.label(text=iface_("and AMD Radeon Pro %s driver or newer") % driver_version,
icon='BLANK1', translate=False)
elif sys.platform.startswith("linux"):
if True:
col.label(text="HIP temporarily disabled due to compiler bugs", icon='BLANK1')
else:
driver_version = "22.10"
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
col.label(text=iface_("and AMD driver version %s or newer") % driver_version, icon='BLANK1',

View File

@ -42,15 +42,19 @@ endif()
###########################################################################
if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
set(WITH_CYCLES_HIP_BINARIES OFF)
message(STATUS "HIP temporarily disabled due to compiler bugs")
if(UNIX)
# Disabled until there is a HIP 5.5 release for Linux.
set(WITH_CYCLES_HIP_BINARIES OFF)
message(STATUS "HIP temporarily disabled due to compiler bugs")
else()
# Need at least HIP 5.5 to solve compiler bug affecting the kernel.
find_package(HIP 5.5.0)
set_and_warn_library_found("HIP compiler" HIP_FOUND WITH_CYCLES_HIP_BINARIES)
# find_package(HIP)
# set_and_warn_library_found("HIP compiler" HIP_FOUND WITH_CYCLES_HIP_BINARIES)
# if(HIP_FOUND)
# message(STATUS "Found HIP ${HIP_HIPCC_EXECUTABLE} (${HIP_VERSION})")
# endif()
if(HIP_FOUND)
message(STATUS "Found HIP ${HIP_HIPCC_EXECUTABLE} (${HIP_VERSION})")
endif()
endif()
endif()
if(NOT WITH_HIP_DYNLOAD)

View File

@ -137,7 +137,7 @@ void device_hip_info(vector<DeviceInfo> &devices)
info.num = num;
info.has_nanovdb = true;
info.has_light_tree = false;
info.has_light_tree = true;
info.denoisers = 0;
info.has_gpu_queue = true;

View File

@ -79,9 +79,8 @@ CCL_NAMESPACE_BEGIN
#define __VISIBILITY_FLAG__
#define __VOLUME__
/* TODO: solve internal compiler errors and enable light tree on HIP. */
/* TODO: solve internal compiler perf issue and enable light tree on Metal/AMD. */
#if defined(__KERNEL_HIP__) || defined(__KERNEL_METAL_AMD__)
#if defined(__KERNEL_METAL_AMD__)
# undef __LIGHT_TREE__
#endif

View File

@ -869,10 +869,10 @@
</space>
<space_list>
<ThemeSpaceListGeneric
list="#181818"
list_title="#ffffff"
list_text="#ffffff"
list_text_hi="#ffffff"
list="#b3b3b3"
list_title="#747474"
list_text="#333333"
list_text_hi="#747474"
>
</ThemeSpaceListGeneric>
</space_list>
@ -1240,7 +1240,7 @@
title="#000000"
text="#000000"
text_hi="#ffffff"
header="#727272ff"
header="#b3b3b3ff"
header_text="#000000"
header_text_hi="#ffffff"
button="#7272727f"
@ -1317,7 +1317,7 @@
title="#ffffff"
text="#ffffff"
text_hi="#ffffff"
header="#999999ff"
header="#b3b3b3ff"
header_text="#1a1a1a"
header_text_hi="#ffffff"
button="#2f303500"

View File

@ -706,6 +706,15 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
bl_label = "Asset Metadata"
bl_options = {'HIDE_HEADER'}
@staticmethod
def metadata_prop(layout, asset_data, propname):
"""
Only display properties that are either set or can be modified (i.e. the
asset is in the current file). Empty, non-editable fields are not really useful.
"""
if getattr(asset_data, propname) or not asset_data.is_property_readonly(propname):
layout.prop(asset_data, propname)
def draw(self, context):
layout = self.layout
wm = context.window_manager
@ -745,10 +754,11 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
row.prop(wm, "asset_path_dummy", text="Source", icon='CURRENT_FILE' if is_local_asset else 'NONE')
row.operator("asset.open_containing_blend_file", text="", icon='TOOL_SETTINGS')
layout.prop(asset_file_handle.asset_data, "description")
layout.prop(asset_file_handle.asset_data, "license")
layout.prop(asset_file_handle.asset_data, "copyright")
layout.prop(asset_file_handle.asset_data, "author")
asset_data = asset_file_handle.asset_data
self.metadata_prop(layout, asset_data, "description")
self.metadata_prop(layout, asset_data, "license")
self.metadata_prop(layout, asset_data, "copyright")
self.metadata_prop(layout, asset_data, "author")
class ASSETBROWSER_PT_metadata_preview(asset_utils.AssetMetaDataPanel, Panel):

View File

@ -28,7 +28,7 @@ bool BKE_curves_attribute_required(const struct Curves *curves, const char *name
/* Depsgraph */
struct Curves *BKE_curves_copy_for_eval(struct Curves *curves_src, bool reference);
struct Curves *BKE_curves_copy_for_eval(struct Curves *curves_src);
void BKE_curves_data_update(struct Depsgraph *depsgraph,
struct Scene *scene,

View File

@ -152,8 +152,6 @@ enum {
LIB_ID_COPY_CACHES = 1 << 18,
/** Don't copy `id->adt`, used by ID data-block localization routines. */
LIB_ID_COPY_NO_ANIMDATA = 1 << 19,
/** Mesh: Reference CD data layers instead of doing real copy - USE WITH CAUTION! */
LIB_ID_COPY_CD_REFERENCE = 1 << 20,
/** Do not copy id->override_library, used by ID data-block override routines. */
LIB_ID_COPY_NO_LIB_OVERRIDE = 1 << 21,
/** When copying local sub-data (like constraints or modifiers), do not set their "library

View File

@ -158,15 +158,15 @@ void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
/** Add poly offsets to describe faces to a new mesh. */
void BKE_mesh_poly_offsets_ensure_alloc(struct Mesh *mesh);
struct Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int loops_len, int polys_len);
struct Mesh *BKE_mesh_new_nomain(int verts_num, int edges_num, int polys_num, int loops_num);
struct Mesh *BKE_mesh_new_nomain_from_template(
const struct Mesh *me_src, int verts_len, int edges_len, int loops_len, int polys_len);
const struct Mesh *me_src, int verts_num, int edges_num, int polys_num, int loops_num);
struct Mesh *BKE_mesh_new_nomain_from_template_ex(const struct Mesh *me_src,
int verts_len,
int edges_len,
int tessface_len,
int loops_len,
int polys_len,
int verts_num,
int edges_num,
int tessface_num,
int polys_num,
int loops_num,
struct CustomData_MeshMasks mask);
void BKE_mesh_eval_delete(struct Mesh *mesh_eval);
@ -175,7 +175,7 @@ void BKE_mesh_eval_delete(struct Mesh *mesh_eval);
* Performs copy for use during evaluation,
* optional referencing original arrays to reduce memory.
*/
struct Mesh *BKE_mesh_copy_for_eval(const struct Mesh *source, bool reference);
struct Mesh *BKE_mesh_copy_for_eval(const struct Mesh *source);
/**
* These functions construct a new Mesh,

View File

@ -298,6 +298,12 @@ typedef struct bNodeType {
void (*freefunc_api)(struct PointerRNA *ptr);
void (*copyfunc_api)(struct PointerRNA *ptr, const struct bNode *src_node);
/**
* An additional poll test for deciding whether nodes should be an option in search menus.
* Potentially more strict poll than #poll(), but doesn't have to check the same things.
*/
bool (*add_ui_poll)(const struct bContext *C);
/**
* Can this node type be added to a node tree?
* \param r_disabled_hint: Hint to display in the UI when the poll fails.

View File

@ -70,8 +70,7 @@ void *BKE_pointcloud_add(struct Main *bmain, const char *name);
void *BKE_pointcloud_add_default(struct Main *bmain, const char *name);
struct PointCloud *BKE_pointcloud_new_nomain(int totpoint);
void BKE_pointcloud_nomain_to_pointcloud(struct PointCloud *pointcloud_src,
struct PointCloud *pointcloud_dst,
bool take_ownership);
struct PointCloud *pointcloud_dst);
struct BoundBox *BKE_pointcloud_boundbox_get(struct Object *ob);
@ -79,7 +78,7 @@ bool BKE_pointcloud_attribute_required(const struct PointCloud *pointcloud, cons
/* Dependency Graph */
struct PointCloud *BKE_pointcloud_copy_for_eval(struct PointCloud *pointcloud_src, bool reference);
struct PointCloud *BKE_pointcloud_copy_for_eval(struct PointCloud *pointcloud_src);
void BKE_pointcloud_data_update(struct Depsgraph *depsgraph,
struct Scene *scene,

View File

@ -53,8 +53,9 @@ typedef struct EditFont {
int selstart, selend;
/**
* Combined styles (#CharInfo.flag) for selected string. A flag will be
* set only if ALL characters in the selected string have it.
* Combined styles from #CharInfo.flag for the selected range selected
* (only including values from #CU_CHINFO_STYLE_ALL).
* A flag will be set only if ALL characters in the selected string have it.
*/
int select_char_info_flag;

View File

@ -130,7 +130,7 @@ void BKE_volume_grid_transform_matrix_set(const struct Volume *volume,
* file path. Grids are shared with the source data-block, not copied. */
struct Volume *BKE_volume_new_for_eval(const struct Volume *volume_src);
struct Volume *BKE_volume_copy_for_eval(struct Volume *volume_src, bool reference);
struct Volume *BKE_volume_copy_for_eval(struct Volume *volume_src);
struct VolumeGrid *BKE_volume_grid_add(struct Volume *volume,
const char *name,

View File

@ -380,7 +380,7 @@ static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer)
BKE_mesh_ensure_default_orig_index_customdata(mesh);
}
else {
mesh = BKE_mesh_copy_for_eval(me, true);
mesh = BKE_mesh_copy_for_eval(me);
}
orco = get_orco_coords(ob, em, layer, &free);
@ -654,7 +654,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
if (ob->modifier_flag & OB_MODIFIER_FLAG_ADD_REST_POSITION) {
if (mesh_final == nullptr) {
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
mesh_final = BKE_mesh_copy_for_eval(mesh_input);
ASSERT_IS_VALID_MESH(mesh_final);
}
MutableAttributeAccessor attributes = mesh_final->attributes_for_write();
@ -685,7 +685,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) {
blender::bke::ScopedModifierTimer modifier_timer{*md};
if (!mesh_final) {
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
mesh_final = BKE_mesh_copy_for_eval(mesh_input);
ASSERT_IS_VALID_MESH(mesh_final);
}
BKE_modifier_deform_verts(md,
@ -703,12 +703,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
* places that wish to use the original mesh but with deformed
* coordinates (like vertex paint). */
if (r_deform) {
if (mesh_final) {
mesh_deform = BKE_mesh_copy_for_eval(mesh_final, false);
}
else {
mesh_deform = BKE_mesh_copy_for_eval(mesh_input, false);
}
mesh_deform = BKE_mesh_copy_for_eval(mesh_final ? mesh_final : mesh_input);
}
}
@ -779,7 +774,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
if (mti->type == eModifierTypeType_OnlyDeform) {
if (!mesh_final) {
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
mesh_final = BKE_mesh_copy_for_eval(mesh_input);
ASSERT_IS_VALID_MESH(mesh_final);
}
BKE_modifier_deform_verts(md,
@ -798,7 +793,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
}
}
else {
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
mesh_final = BKE_mesh_copy_for_eval(mesh_input);
ASSERT_IS_VALID_MESH(mesh_final);
check_for_needs_mapping = true;
}
@ -966,7 +961,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
mesh_final = mesh_input;
}
else {
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
mesh_final = BKE_mesh_copy_for_eval(mesh_input);
}
}
@ -1011,7 +1006,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
/* Not yet finalized by any instance, do it now
* Isolate since computing normals is multithreaded and we are holding a lock. */
blender::threading::isolate_task([&] {
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
mesh_final = BKE_mesh_copy_for_eval(mesh_input);
mesh_calc_modifier_final_normals(
mesh_input, &final_datamask, sculpt_dyntopo, mesh_final);
mesh_calc_finalize(mesh_input, mesh_final);
@ -1026,7 +1021,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
else if (!mesh_has_modifier_final_normals(mesh_input, &final_datamask, runtime->mesh_eval)) {
/* Modifier stack was (re-)evaluated with a request for additional normals
* different than the instanced mesh, can't instance anymore now. */
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
mesh_final = BKE_mesh_copy_for_eval(mesh_input);
mesh_calc_modifier_final_normals(mesh_input, &final_datamask, sculpt_dyntopo, mesh_final);
mesh_calc_finalize(mesh_input, mesh_final);
}
@ -1255,7 +1250,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
/* apply vertex coordinates or build a DerivedMesh as necessary */
if (mesh_final) {
if (deformed_verts) {
Mesh *mesh_tmp = BKE_mesh_copy_for_eval(mesh_final, false);
Mesh *mesh_tmp = BKE_mesh_copy_for_eval(mesh_final);
if (mesh_final != mesh_cage) {
BKE_id_free(nullptr, mesh_final);
}
@ -1264,7 +1259,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
}
else if (mesh_final == mesh_cage) {
/* 'me' may be changed by this modifier, so we need to copy it. */
mesh_final = BKE_mesh_copy_for_eval(mesh_final, false);
mesh_final = BKE_mesh_copy_for_eval(mesh_final);
}
}
else {
@ -1337,7 +1332,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
if (r_cage && i == cageIndex) {
if (mesh_final && deformed_verts) {
mesh_cage = BKE_mesh_copy_for_eval(mesh_final, false);
mesh_cage = BKE_mesh_copy_for_eval(mesh_final);
BKE_mesh_vert_coords_apply(mesh_cage, deformed_verts);
}
else if (mesh_final) {
@ -1373,7 +1368,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
if (mesh_final) {
if (deformed_verts) {
if (mesh_final == mesh_cage) {
mesh_final = BKE_mesh_copy_for_eval(mesh_final, false);
mesh_final = BKE_mesh_copy_for_eval(mesh_final);
}
BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
}

View File

@ -399,7 +399,7 @@ bool BKE_cachefile_filepath_get(const Main *bmain,
const int frame = (int)BKE_cachefile_time_offset(cache_file, (double)ctime, fps);
char ext[32];
BLI_path_frame_strip(r_filepath, ext);
BLI_path_frame_strip(r_filepath, ext, sizeof(ext));
BLI_path_frame(r_filepath, frame, frame_len);
BLI_path_extension_ensure(r_filepath, FILE_MAX, ext);

View File

@ -1176,7 +1176,7 @@ static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh)
static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh)
{
using namespace blender;
Mesh *new_mesh = BKE_mesh_copy_for_eval(mesh, false);
Mesh *new_mesh = BKE_mesh_copy_for_eval(mesh);
ClothVertex *verts = clmd->clothObject->verts;
MutableSpan<float3> positions = mesh->vert_positions_for_write();

View File

@ -389,7 +389,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph,
if (defmats == nullptr) {
/* NOTE: Evaluated object is re-set to its original un-deformed state. */
Mesh *me = static_cast<Mesh *>(object_eval.data);
me_eval = BKE_mesh_copy_for_eval(me, true);
me_eval = BKE_mesh_copy_for_eval(me);
crazyspace_init_verts_and_matrices(me_eval, &defmats, &deformedVerts);
}
@ -470,7 +470,7 @@ void BKE_crazyspace_build_sculpt(struct Depsgraph *depsgraph,
}
if (mesh_eval == nullptr) {
mesh_eval = BKE_mesh_copy_for_eval(mesh, true);
mesh_eval = BKE_mesh_copy_for_eval(mesh);
}
mti->deformVerts(md, &mectx, mesh_eval, deformedVerts, mesh_eval->totvert);

View File

@ -691,7 +691,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
}
Mesh *mesh = BKE_mesh_new_nomain(
offsets.vert.last(), offsets.edge.last(), offsets.loop.last(), offsets.poly.last());
offsets.vert.last(), offsets.edge.last(), offsets.poly.last(), offsets.loop.last());
mesh->flag |= ME_AUTOSMOOTH;
mesh->smoothresh = DEG2RADF(180.0f);
MutableSpan<float3> positions = mesh->vert_positions_for_write();

View File

@ -220,16 +220,10 @@ bool BKE_curves_attribute_required(const Curves * /*curves*/, const char *name)
return STREQ(name, ATTR_POSITION);
}
Curves *BKE_curves_copy_for_eval(Curves *curves_src, bool reference)
Curves *BKE_curves_copy_for_eval(Curves *curves_src)
{
int flags = LIB_ID_COPY_LOCALIZE;
if (reference) {
flags |= LIB_ID_COPY_CD_REFERENCE;
}
Curves *result = (Curves *)BKE_id_copy_ex(nullptr, &curves_src->id, nullptr, flags);
return result;
return reinterpret_cast<Curves *>(
BKE_id_copy_ex(nullptr, &curves_src->id, nullptr, LIB_ID_COPY_LOCALIZE));
}
static void curves_evaluate_modifiers(struct Depsgraph *depsgraph,

View File

@ -1904,7 +1904,7 @@ static void dynamic_paint_apply_surface_wave_cb(void *__restrict userdata,
*/
static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *ob, Mesh *mesh)
{
Mesh *result = BKE_mesh_copy_for_eval(mesh, false);
Mesh *result = BKE_mesh_copy_for_eval(mesh);
if (pmd->canvas && !(pmd->canvas->flags & MOD_DPAINT_BAKING) &&
pmd->type == MOD_DYNAMICPAINT_TYPE_CANVAS) {
@ -2049,7 +2049,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
if (runtime_data->brush_mesh != nullptr) {
BKE_id_free(nullptr, runtime_data->brush_mesh);
}
runtime_data->brush_mesh = BKE_mesh_copy_for_eval(result, false);
runtime_data->brush_mesh = BKE_mesh_copy_for_eval(result);
}
return result;
@ -2070,7 +2070,7 @@ static void canvas_copyMesh(DynamicPaintCanvasSettings *canvas, Mesh *mesh)
BKE_id_free(nullptr, runtime->canvas_mesh);
}
runtime->canvas_mesh = BKE_mesh_copy_for_eval(mesh, false);
runtime->canvas_mesh = BKE_mesh_copy_for_eval(mesh);
}
/*
@ -3796,7 +3796,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
SUBFRAME_RECURSION,
BKE_scene_ctime_get(scene),
eModifierType_DynamicPaint);
mesh_p = BKE_mesh_copy_for_eval(dynamicPaint_brush_mesh_get(brush), false);
mesh_p = BKE_mesh_copy_for_eval(dynamicPaint_brush_mesh_get(brush));
numOfVerts_p = mesh_p->totvert;
float(*positions_p)[3] = BKE_mesh_vert_positions_for_write(mesh_p);
@ -4282,7 +4282,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
Bounds3D mesh_bb = {{0}};
VolumeGrid *grid = bData->grid;
mesh = BKE_mesh_copy_for_eval(brush_mesh, false);
mesh = BKE_mesh_copy_for_eval(brush_mesh);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh);
const blender::Span<blender::float3> vert_normals = mesh->vert_normals();
const blender::Span<int> corner_verts = mesh->corner_verts();

View File

@ -1003,7 +1003,7 @@ static void obstacles_from_mesh(Object *coll_ob,
float *vert_vel = nullptr;
bool has_velocity = false;
Mesh *me = BKE_mesh_copy_for_eval(fes->mesh, false);
Mesh *me = BKE_mesh_copy_for_eval(fes->mesh);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(me);
int min[3], max[3], res[3];
@ -2062,7 +2062,7 @@ static void emit_from_mesh(
/* Copy mesh for thread safety as we modify it.
* Main issue is its VertArray being modified, then replaced and freed. */
Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh, false);
Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(me);
const blender::Span<int> corner_verts = me->corner_verts();
@ -3229,7 +3229,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
return nullptr;
}
me = BKE_mesh_new_nomain(num_verts, 0, num_faces * 3, num_faces);
me = BKE_mesh_new_nomain(num_verts, 0, num_faces, num_faces * 3);
if (!me) {
return nullptr;
}
@ -3364,10 +3364,10 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje
/* Just copy existing mesh if there is no content or if the adaptive domain is not being used. */
if (fds->total_cells <= 1 || (fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) == 0) {
return BKE_mesh_copy_for_eval(orgmesh, false);
return BKE_mesh_copy_for_eval(orgmesh);
}
result = BKE_mesh_new_nomain(num_verts, 0, num_faces * 4, num_faces);
result = BKE_mesh_new_nomain(num_verts, 0, num_faces, num_faces * 4);
float(*positions)[3] = BKE_mesh_vert_positions_for_write(result);
blender::MutableSpan<int> poly_offsets = result->poly_offsets_for_write();
blender::MutableSpan<int> corner_verts = result->corner_verts_for_write();
@ -3590,7 +3590,7 @@ static void fluid_modifier_processFlow(FluidModifierData *fmd,
if (fmd->flow->mesh) {
BKE_id_free(nullptr, fmd->flow->mesh);
}
fmd->flow->mesh = BKE_mesh_copy_for_eval(me, false);
fmd->flow->mesh = BKE_mesh_copy_for_eval(me);
}
if (scene_framenr > fmd->time) {
@ -3617,7 +3617,7 @@ static void fluid_modifier_processEffector(FluidModifierData *fmd,
if (fmd->effector->mesh) {
BKE_id_free(nullptr, fmd->effector->mesh);
}
fmd->effector->mesh = BKE_mesh_copy_for_eval(me, false);
fmd->effector->mesh = BKE_mesh_copy_for_eval(me);
}
if (scene_framenr > fmd->time) {
@ -4125,7 +4125,7 @@ Mesh *BKE_fluid_modifier_do(
}
if (!result) {
result = BKE_mesh_copy_for_eval(me, false);
result = BKE_mesh_copy_for_eval(me);
}
else {
BKE_mesh_copy_parameters_for_eval(result, me);

View File

@ -33,7 +33,7 @@ GeometryComponent *CurveComponent::copy() const
{
CurveComponent *new_component = new CurveComponent();
if (curves_ != nullptr) {
new_component->curves_ = BKE_curves_copy_for_eval(curves_, false);
new_component->curves_ = BKE_curves_copy_for_eval(curves_);
new_component->ownership_ = GeometryOwnershipType::Owned;
}
return new_component;
@ -87,7 +87,7 @@ Curves *CurveComponent::get_for_write()
{
BLI_assert(this->is_mutable());
if (ownership_ == GeometryOwnershipType::ReadOnly) {
curves_ = BKE_curves_copy_for_eval(curves_, false);
curves_ = BKE_curves_copy_for_eval(curves_);
ownership_ = GeometryOwnershipType::Owned;
}
return curves_;
@ -107,7 +107,7 @@ void CurveComponent::ensure_owns_direct_data()
{
BLI_assert(this->is_mutable());
if (ownership_ != GeometryOwnershipType::Owned) {
curves_ = BKE_curves_copy_for_eval(curves_, false);
curves_ = BKE_curves_copy_for_eval(curves_);
ownership_ = GeometryOwnershipType::Owned;
}
}

View File

@ -36,7 +36,7 @@ GeometryComponent *MeshComponent::copy() const
{
MeshComponent *new_component = new MeshComponent();
if (mesh_ != nullptr) {
new_component->mesh_ = BKE_mesh_copy_for_eval(mesh_, false);
new_component->mesh_ = BKE_mesh_copy_for_eval(mesh_);
new_component->ownership_ = GeometryOwnershipType::Owned;
}
return new_component;
@ -83,7 +83,7 @@ Mesh *MeshComponent::get_for_write()
{
BLI_assert(this->is_mutable());
if (ownership_ == GeometryOwnershipType::ReadOnly) {
mesh_ = BKE_mesh_copy_for_eval(mesh_, false);
mesh_ = BKE_mesh_copy_for_eval(mesh_);
ownership_ = GeometryOwnershipType::Owned;
}
return mesh_;
@ -103,7 +103,7 @@ void MeshComponent::ensure_owns_direct_data()
{
BLI_assert(this->is_mutable());
if (ownership_ != GeometryOwnershipType::Owned) {
mesh_ = BKE_mesh_copy_for_eval(mesh_, false);
mesh_ = BKE_mesh_copy_for_eval(mesh_);
ownership_ = GeometryOwnershipType::Owned;
}
}

View File

@ -23,7 +23,7 @@ GeometryComponent *PointCloudComponent::copy() const
{
PointCloudComponent *new_component = new PointCloudComponent();
if (pointcloud_ != nullptr) {
new_component->pointcloud_ = BKE_pointcloud_copy_for_eval(pointcloud_, false);
new_component->pointcloud_ = BKE_pointcloud_copy_for_eval(pointcloud_);
new_component->ownership_ = GeometryOwnershipType::Owned;
}
return new_component;
@ -70,7 +70,7 @@ PointCloud *PointCloudComponent::get_for_write()
{
BLI_assert(this->is_mutable());
if (ownership_ == GeometryOwnershipType::ReadOnly) {
pointcloud_ = BKE_pointcloud_copy_for_eval(pointcloud_, false);
pointcloud_ = BKE_pointcloud_copy_for_eval(pointcloud_);
ownership_ = GeometryOwnershipType::Owned;
}
return pointcloud_;
@ -90,7 +90,7 @@ void PointCloudComponent::ensure_owns_direct_data()
{
BLI_assert(this->is_mutable());
if (ownership_ != GeometryOwnershipType::Owned) {
pointcloud_ = BKE_pointcloud_copy_for_eval(pointcloud_, false);
pointcloud_ = BKE_pointcloud_copy_for_eval(pointcloud_);
ownership_ = GeometryOwnershipType::Owned;
}
}

View File

@ -21,7 +21,7 @@ GeometryComponent *VolumeComponent::copy() const
{
VolumeComponent *new_component = new VolumeComponent();
if (volume_ != nullptr) {
new_component->volume_ = BKE_volume_copy_for_eval(volume_, false);
new_component->volume_ = BKE_volume_copy_for_eval(volume_);
new_component->ownership_ = GeometryOwnershipType::Owned;
}
return new_component;
@ -68,7 +68,7 @@ Volume *VolumeComponent::get_for_write()
{
BLI_assert(this->is_mutable());
if (ownership_ == GeometryOwnershipType::ReadOnly) {
volume_ = BKE_volume_copy_for_eval(volume_, false);
volume_ = BKE_volume_copy_for_eval(volume_);
ownership_ = GeometryOwnershipType::Owned;
}
return volume_;
@ -83,7 +83,7 @@ void VolumeComponent::ensure_owns_direct_data()
{
BLI_assert(this->is_mutable());
if (ownership_ != GeometryOwnershipType::Owned) {
volume_ = BKE_volume_copy_for_eval(volume_, false);
volume_ = BKE_volume_copy_for_eval(volume_);
ownership_ = GeometryOwnershipType::Owned;
}
}

View File

@ -1451,18 +1451,17 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
freepolygonize(&process);
Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)ob->data)->name + 2);
int corners_num = 0;
for (uint i = 0; i < process.curindex; i++) {
const int *indices = process.indices[i];
const int count = indices[2] != indices[3] ? 4 : 3;
corners_num += count;
}
mesh->totvert = int(process.co.size());
CustomData_add_layer_named(
&mesh->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, mesh->totvert, "position");
Mesh *mesh = BKE_mesh_new_nomain(int(process.co.size()), 0, int(process.curindex), corners_num);
mesh->vert_positions_for_write().copy_from(process.co);
mesh->totpoly = int(process.curindex);
BKE_mesh_poly_offsets_ensure_alloc(mesh);
blender::MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
int *corner_verts = static_cast<int *>(CustomData_add_layer_named(
&mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh->totpoly * 4, ".corner_vert"));
blender::MutableSpan<int> corner_verts = mesh->corner_verts_for_write();
int loop_offset = 0;
for (int i = 0; i < mesh->totpoly; i++) {
@ -1490,9 +1489,6 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
sizeof(float[3]) * size_t(mesh->totvert));
BKE_mesh_vert_normals_clear_dirty(mesh);
mesh->totloop = loop_offset;
poly_offsets.last() = loop_offset;
BKE_mesh_calc_edges(mesh, false, false);
return mesh;

View File

@ -1032,23 +1032,19 @@ static void mesh_ensure_cdlayers_primary(Mesh &mesh)
}
}
Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int loops_len, int polys_len)
Mesh *BKE_mesh_new_nomain(const int verts_num,
const int edges_num,
const int polys_num,
const int loops_num)
{
Mesh *mesh = (Mesh *)BKE_libblock_alloc(
nullptr, ID_ME, BKE_idtype_idcode_to_name(ID_ME), LIB_ID_CREATE_LOCALIZE);
Mesh *mesh = static_cast<Mesh *>(BKE_libblock_alloc(
nullptr, ID_ME, BKE_idtype_idcode_to_name(ID_ME), LIB_ID_CREATE_LOCALIZE));
BKE_libblock_init_empty(&mesh->id);
/* Don't use #CustomData_reset because we don't want to touch custom-data. */
copy_vn_i(mesh->vdata.typemap, CD_NUMTYPES, -1);
copy_vn_i(mesh->edata.typemap, CD_NUMTYPES, -1);
copy_vn_i(mesh->fdata.typemap, CD_NUMTYPES, -1);
copy_vn_i(mesh->ldata.typemap, CD_NUMTYPES, -1);
copy_vn_i(mesh->pdata.typemap, CD_NUMTYPES, -1);
mesh->totvert = verts_len;
mesh->totedge = edges_len;
mesh->totloop = loops_len;
mesh->totpoly = polys_len;
mesh->totvert = verts_num;
mesh->totedge = edges_num;
mesh->totpoly = polys_num;
mesh->totloop = loops_num;
mesh_ensure_cdlayers_primary(*mesh);
BKE_mesh_poly_offsets_ensure_alloc(mesh);
@ -1112,35 +1108,35 @@ void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
}
Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
int verts_len,
int edges_len,
int tessface_len,
int loops_len,
int polys_len,
CustomData_MeshMasks mask)
const int verts_num,
const int edges_num,
const int tessface_num,
const int polys_num,
const int loops_num,
const CustomData_MeshMasks mask)
{
/* Only do tessface if we are creating tessfaces or copying from mesh with only tessfaces. */
const bool do_tessface = (tessface_len || ((me_src->totface != 0) && (me_src->totpoly == 0)));
const bool do_tessface = (tessface_num || ((me_src->totface != 0) && (me_src->totpoly == 0)));
Mesh *me_dst = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr);
me_dst->mselect = (MSelect *)MEM_dupallocN(me_src->mselect);
me_dst->totvert = verts_len;
me_dst->totedge = edges_len;
me_dst->totface = tessface_len;
me_dst->totloop = loops_len;
me_dst->totpoly = polys_len;
me_dst->totvert = verts_num;
me_dst->totedge = edges_num;
me_dst->totpoly = polys_num;
me_dst->totloop = loops_num;
me_dst->totface = tessface_num;
BKE_mesh_copy_parameters_for_eval(me_dst, me_src);
CustomData_copy_layout(&me_src->vdata, &me_dst->vdata, mask.vmask, CD_SET_DEFAULT, verts_len);
CustomData_copy_layout(&me_src->edata, &me_dst->edata, mask.emask, CD_SET_DEFAULT, edges_len);
CustomData_copy_layout(&me_src->ldata, &me_dst->ldata, mask.lmask, CD_SET_DEFAULT, loops_len);
CustomData_copy_layout(&me_src->pdata, &me_dst->pdata, mask.pmask, CD_SET_DEFAULT, polys_len);
CustomData_copy_layout(&me_src->vdata, &me_dst->vdata, mask.vmask, CD_SET_DEFAULT, verts_num);
CustomData_copy_layout(&me_src->edata, &me_dst->edata, mask.emask, CD_SET_DEFAULT, edges_num);
CustomData_copy_layout(&me_src->pdata, &me_dst->pdata, mask.pmask, CD_SET_DEFAULT, polys_num);
CustomData_copy_layout(&me_src->ldata, &me_dst->ldata, mask.lmask, CD_SET_DEFAULT, loops_num);
if (do_tessface) {
CustomData_copy_layout(
&me_src->fdata, &me_dst->fdata, mask.fmask, CD_SET_DEFAULT, tessface_len);
&me_src->fdata, &me_dst->fdata, mask.fmask, CD_SET_DEFAULT, tessface_num);
}
else {
mesh_tessface_clear_intern(me_dst, false);
@ -1160,11 +1156,14 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
return me_dst;
}
Mesh *BKE_mesh_new_nomain_from_template(
const Mesh *me_src, int verts_len, int edges_len, int loops_len, int polys_len)
Mesh *BKE_mesh_new_nomain_from_template(const Mesh *me_src,
const int verts_num,
const int edges_num,
const int polys_num,
const int loops_num)
{
return BKE_mesh_new_nomain_from_template_ex(
me_src, verts_len, edges_len, 0, loops_len, polys_len, CD_MASK_EVERYTHING);
me_src, verts_num, edges_num, 0, polys_num, loops_num, CD_MASK_EVERYTHING);
}
void BKE_mesh_eval_delete(struct Mesh *mesh_eval)
@ -1176,16 +1175,10 @@ void BKE_mesh_eval_delete(struct Mesh *mesh_eval)
MEM_freeN(mesh_eval);
}
Mesh *BKE_mesh_copy_for_eval(const Mesh *source, bool reference)
Mesh *BKE_mesh_copy_for_eval(const Mesh *source)
{
int flags = LIB_ID_COPY_LOCALIZE;
if (reference) {
flags |= LIB_ID_COPY_CD_REFERENCE;
}
Mesh *result = (Mesh *)BKE_id_copy_ex(nullptr, &source->id, nullptr, flags);
return result;
return reinterpret_cast<Mesh *>(
BKE_id_copy_ex(nullptr, &source->id, nullptr, LIB_ID_COPY_LOCALIZE));
}
BMesh *BKE_mesh_to_bmesh_ex(const Mesh *me,

View File

@ -700,7 +700,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
}
/* Will calculate edges later. */
Mesh *result = BKE_mesh_new_nomain_from_template(
mim.meshes[0], out_totvert, 0, out_totloop, out_totpoly);
mim.meshes[0], out_totvert, 0, out_totpoly, out_totloop);
merge_vertex_loop_poly_customdata_layers(result, mim);
/* Set the vertex coordinate values and other data. */

View File

@ -151,14 +151,13 @@ static void serialize_and_initialize_deduplicated_edges(MutableSpan<EdgeMap> edg
});
}
static void update_edge_indices_in_poly_loops(Mesh *mesh,
Span<EdgeMap> edge_maps,
uint32_t parallel_mask)
static void update_edge_indices_in_poly_loops(const OffsetIndices<int> polys,
const Span<int> corner_verts,
const Span<EdgeMap> edge_maps,
const uint32_t parallel_mask,
MutableSpan<int> corner_edges)
{
const OffsetIndices polys = mesh->polys();
const Span<int> corner_verts = mesh->corner_verts();
MutableSpan<int> corner_edges = mesh->corner_edges_for_write();
threading::parallel_for(IndexRange(mesh->totpoly), 100, [&](IndexRange range) {
threading::parallel_for(polys.index_range(), 100, [&](IndexRange range) {
for (const int poly_index : range) {
const IndexRange poly = polys[poly_index];
int prev_corner = poly.last();
@ -239,7 +238,11 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
MutableSpan<int2> new_edges{
static_cast<int2 *>(MEM_calloc_arrayN(new_totedge, sizeof(int2), __func__)), new_totedge};
calc_edges::serialize_and_initialize_deduplicated_edges(edge_maps, new_edges);
calc_edges::update_edge_indices_in_poly_loops(mesh, edge_maps, parallel_mask);
calc_edges::update_edge_indices_in_poly_loops(mesh->polys(),
mesh->corner_verts(),
edge_maps,
parallel_mask,
mesh->corner_edges_for_write());
/* Free old CustomData and assign new one. */
CustomData_free(&mesh->edata, mesh->totedge);

View File

@ -62,98 +62,8 @@ using blender::MutableSpan;
using blender::Span;
using blender::StringRefNull;
/* Define for cases when you want extra validation of mesh
* after certain modifications.
*/
// #undef VALIDATE_MESH
#ifdef VALIDATE_MESH
# define ASSERT_IS_VALID_MESH(mesh) \
(BLI_assert((mesh == nullptr) || (BKE_mesh_is_valid(mesh) == true)))
#else
# define ASSERT_IS_VALID_MESH(mesh)
#endif
static CLG_LogRef LOG = {"bke.mesh_convert"};
static void poly_edgehash_insert(EdgeHash *ehash, const Span<int> poly_verts)
{
int i = poly_verts.size();
int next = 0; /* first loop */
int poly_corner = (i - 1); /* last loop */
while (i-- != 0) {
BLI_edgehash_reinsert(ehash, poly_verts[poly_corner], poly_verts[next], nullptr);
poly_corner = next;
next++;
}
}
/**
* Specialized function to use when we _know_ existing edges don't overlap with poly edges.
*/
static void make_edges_mdata_extend(Mesh &mesh)
{
int totedge = mesh.totedge;
const blender::OffsetIndices polys = mesh.polys();
const Span<int> corner_verts = mesh.corner_verts();
MutableSpan<int> corner_edges = mesh.corner_edges_for_write();
const int eh_reserve = max_ii(totedge, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(mesh.totpoly));
EdgeHash *eh = BLI_edgehash_new_ex(__func__, eh_reserve);
for (const int i : polys.index_range()) {
poly_edgehash_insert(eh, corner_verts.slice(polys[i]));
}
const int totedge_new = BLI_edgehash_len(eh);
#ifdef DEBUG
/* ensure that there's no overlap! */
if (totedge_new) {
for (const blender::int2 &edge : mesh.edges()) {
BLI_assert(BLI_edgehash_haskey(eh, edge[0], edge[1]) == false);
}
}
#endif
if (totedge_new) {
/* The only layer should be edges, so no other layers need to be initialized. */
BLI_assert(mesh.edata.totlayer == 1);
CustomData_realloc(&mesh.edata, totedge, totedge + totedge_new);
mesh.totedge += totedge_new;
MutableSpan<blender::int2> edges = mesh.edges_for_write();
blender::int2 *edge = &edges[totedge];
EdgeHashIterator *ehi;
uint e_index = totedge;
for (ehi = BLI_edgehashIterator_new(eh); BLI_edgehashIterator_isDone(ehi) == false;
BLI_edgehashIterator_step(ehi), ++edge, e_index++) {
BLI_edgehashIterator_getKey(ehi, &(*edge)[0], &(*edge)[1]);
BLI_edgehashIterator_setValue(ehi, POINTER_FROM_UINT(e_index));
}
BLI_edgehashIterator_free(ehi);
for (const int i : polys.index_range()) {
const IndexRange poly = polys[i];
int corner = poly.start();
int corner_prev = poly.start() + (poly.size() - 1);
int j;
for (j = 0; j < poly.size(); j++, corner++) {
/* lookup hashed edge index */
corner_edges[corner_prev] = POINTER_AS_UINT(
BLI_edgehash_lookup(eh, corner_verts[corner_prev], corner_verts[corner]));
corner_prev = corner;
}
}
}
BLI_edgehash_free(eh, nullptr);
}
static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispbase)
{
using namespace blender::bke;
@ -203,7 +113,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
return BKE_mesh_new_nomain(0, 0, 0, 0);
}
Mesh *mesh = BKE_mesh_new_nomain(totvert, totedge, totloop, totpoly);
Mesh *mesh = BKE_mesh_new_nomain(totvert, totedge, totpoly, totloop);
MutableSpan<float3> positions = mesh->vert_positions_for_write();
MutableSpan<blender::int2> edges = mesh->edges_for_write();
MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
@ -393,7 +303,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
}
if (totpoly) {
make_edges_mdata_extend(*mesh);
BKE_mesh_calc_edges(mesh, true, false);
}
material_indices.finish();
@ -783,7 +693,7 @@ static const Curves *get_evaluated_curves_from_object(const Object *object)
static Mesh *mesh_new_from_evaluated_curve_type_object(const Object *evaluated_object)
{
if (const Mesh *mesh = BKE_object_get_evaluated_mesh(evaluated_object)) {
return BKE_mesh_copy_for_eval(mesh, false);
return BKE_mesh_copy_for_eval(mesh);
}
if (const Curves *curves = get_evaluated_curves_from_object(evaluated_object)) {
const blender::bke::AnonymousAttributePropagationInfo propagation_info;
@ -842,7 +752,7 @@ static Mesh *mesh_new_from_mball_object(Object *object)
return (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
}
return BKE_mesh_copy_for_eval(mesh_eval, false);
return BKE_mesh_copy_for_eval(mesh_eval);
}
static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh)

View File

@ -2197,7 +2197,10 @@ void BKE_mesh_legacy_attribute_strings_to_flags(Mesh *mesh)
CustomData_clear_layer_flag(
vdata, CD_PROP_BYTE_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
CustomData_clear_layer_flag(
ldata, CD_PROP_BYTE_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
CustomData_clear_layer_flag(ldata, CD_PROP_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
CustomData_clear_layer_flag(vdata, CD_PROP_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
if (const char *name = mesh->active_color_attribute) {
int i;

View File

@ -191,7 +191,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
const int src_loops_num = mesh->totloop;
Mesh *result = BKE_mesh_new_nomain_from_template(
mesh, src_verts_num * 2, src_edges_num * 2, src_loops_num * 2, src_polys.size() * 2);
mesh, src_verts_num * 2, src_edges_num * 2, src_polys.size() * 2, src_loops_num * 2);
/* Copy custom-data to original geometry. */
CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, src_verts_num);

View File

@ -117,7 +117,7 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
}
/* Construct the new output mesh */
Mesh *mesh = BKE_mesh_new_nomain(qrd.out_totverts, 0, qrd.out_totfaces * 4, qrd.out_totfaces);
Mesh *mesh = BKE_mesh_new_nomain(qrd.out_totverts, 0, qrd.out_totfaces, qrd.out_totfaces * 4);
BKE_mesh_copy_parameters(mesh, input_mesh);
MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
MutableSpan<int> corner_verts = mesh->corner_verts_for_write();
@ -222,7 +222,7 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set
*level_set_grid, vertices, tris, quads, isovalue, adaptivity, relax_disoriented_triangles);
Mesh *mesh = BKE_mesh_new_nomain(
vertices.size(), 0, quads.size() * 4 + tris.size() * 3, quads.size() + tris.size());
vertices.size(), 0, quads.size() + tris.size(), quads.size() * 4 + tris.size() * 3);
MutableSpan<float3> vert_positions = mesh->vert_positions_for_write();
MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
MutableSpan<int> mesh_corner_verts = mesh->corner_verts_for_write();
@ -317,8 +317,7 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
const OffsetIndices target_polys = target->polys();
const Span<int> target_corner_verts = target->corner_verts();
const VArray src_face_sets =
* src_attributes.lookup<int>(".sculpt_face_set", ATTR_DOMAIN_FACE);
const VArray src_face_sets = *src_attributes.lookup<int>(".sculpt_face_set", ATTR_DOMAIN_FACE);
if (!src_face_sets) {
return;
}

View File

@ -241,7 +241,7 @@ Mesh *BKE_multires_create_mesh(struct Depsgraph *depsgraph,
Mesh *result = mti->modifyMesh(&mmd->modifier, &modifier_ctx, deformed_mesh);
if (result == deformed_mesh) {
result = BKE_mesh_copy_for_eval(deformed_mesh, true);
result = BKE_mesh_copy_for_eval(deformed_mesh);
}
return result;
}

View File

@ -249,9 +249,7 @@ PointCloud *BKE_pointcloud_new_nomain(const int totpoint)
return pointcloud;
}
void BKE_pointcloud_nomain_to_pointcloud(PointCloud *pointcloud_src,
PointCloud *pointcloud_dst,
bool take_ownership)
void BKE_pointcloud_nomain_to_pointcloud(PointCloud *pointcloud_src, PointCloud *pointcloud_dst)
{
BLI_assert(pointcloud_src->id.tag & LIB_TAG_NO_MAIN);
@ -260,9 +258,7 @@ void BKE_pointcloud_nomain_to_pointcloud(PointCloud *pointcloud_src,
const int totpoint = pointcloud_dst->totpoint = pointcloud_src->totpoint;
CustomData_copy(&pointcloud_src->pdata, &pointcloud_dst->pdata, CD_MASK_ALL, totpoint);
if (take_ownership) {
BKE_id_free(nullptr, pointcloud_src);
}
BKE_id_free(nullptr, pointcloud_src);
}
bool PointCloud::bounds_min_max(blender::float3 &min, blender::float3 &max) const
@ -322,16 +318,10 @@ bool BKE_pointcloud_attribute_required(const PointCloud * /*pointcloud*/, const
/* Dependency Graph */
PointCloud *BKE_pointcloud_copy_for_eval(struct PointCloud *pointcloud_src, bool reference)
PointCloud *BKE_pointcloud_copy_for_eval(struct PointCloud *pointcloud_src)
{
int flags = LIB_ID_COPY_LOCALIZE;
if (reference) {
flags |= LIB_ID_COPY_CD_REFERENCE;
}
PointCloud *result = (PointCloud *)BKE_id_copy_ex(nullptr, &pointcloud_src->id, nullptr, flags);
return result;
return reinterpret_cast<PointCloud *>(
BKE_id_copy_ex(nullptr, &pointcloud_src->id, nullptr, LIB_ID_COPY_LOCALIZE));
}
static void pointcloud_evaluate_modifiers(struct Depsgraph *depsgraph,

View File

@ -532,7 +532,7 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex
SubdivMeshContext *subdiv_context = static_cast<SubdivMeshContext *>(foreach_context->user_data);
subdiv_context->subdiv_mesh = BKE_mesh_new_nomain_from_template_ex(
subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons, mask);
subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_polygons, num_loops, mask);
subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context);
subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices);
subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags.clear();

View File

@ -1143,8 +1143,7 @@ static bool vfont_to_curve(Object *ob,
if (ef && ef->selboxes) {
/* Set combined style flags for the selected string. Start with all styles then
* remove one if ANY characters do not have it. Break out if we've removed them all. */
ef->select_char_info_flag = CU_CHINFO_BOLD | CU_CHINFO_ITALIC | CU_CHINFO_UNDERLINE |
CU_CHINFO_SMALLCAPS;
ef->select_char_info_flag = CU_CHINFO_STYLE_ALL;
for (int k = selstart; k <= selend && ef->select_char_info_flag; k++) {
info = &custrinfo[k];
ef->select_char_info_flag &= info->flag;

View File

@ -768,7 +768,7 @@ static void volume_filepath_get(const Main *bmain, const Volume *volume, char r_
int path_frame, path_digits;
if (volume->is_sequence && BLI_path_frame_get(r_filepath, &path_frame, &path_digits)) {
char ext[32];
BLI_path_frame_strip(r_filepath, ext);
BLI_path_frame_strip(r_filepath, ext, sizeof(ext));
BLI_path_frame(r_filepath, volume->runtime.frame, path_digits);
BLI_path_extension_ensure(r_filepath, FILE_MAX, ext);
}
@ -1523,17 +1523,10 @@ Volume *BKE_volume_new_for_eval(const Volume *volume_src)
return volume_dst;
}
Volume *BKE_volume_copy_for_eval(Volume *volume_src, bool reference)
Volume *BKE_volume_copy_for_eval(Volume *volume_src)
{
int flags = LIB_ID_COPY_LOCALIZE;
if (reference) {
flags |= LIB_ID_COPY_CD_REFERENCE;
}
Volume *result = (Volume *)BKE_id_copy_ex(nullptr, &volume_src->id, nullptr, flags);
return result;
return reinterpret_cast<Volume *>(
BKE_id_copy_ex(nullptr, &volume_src->id, nullptr, LIB_ID_COPY_LOCALIZE));
}
#ifdef WITH_OPENVDB

View File

@ -165,7 +165,7 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid,
const int tot_loops = 3 * mesh_data.tris.size() + 4 * mesh_data.quads.size();
const int tot_polys = mesh_data.tris.size() + mesh_data.quads.size();
Mesh *mesh = BKE_mesh_new_nomain(mesh_data.verts.size(), 0, tot_loops, tot_polys);
Mesh *mesh = BKE_mesh_new_nomain(mesh_data.verts.size(), 0, tot_polys, tot_loops);
fill_mesh_from_openvdb_data(mesh_data.verts,
mesh_data.tris,

View File

@ -118,7 +118,7 @@ ENUM_OPERATORS(eFileAttributes, FILE_ATTR_HARDLINK);
* \{ */
typedef enum FileExternalOperation {
FILE_EXTERNAL_OPERATION_OPEN = 0,
FILE_EXTERNAL_OPERATION_OPEN = 1,
FILE_EXTERNAL_OPERATION_FOLDER_OPEN,
/* Following are Windows-only: */
FILE_EXTERNAL_OPERATION_EDIT,

View File

@ -60,6 +60,12 @@ void BLI_split_dir_part(const char *string, char *dir, size_t dirlen);
* Copies the leaf filename part of string into `file`, max length `filelen`.
*/
void BLI_split_file_part(const char *string, char *file, size_t filelen);
/**
* Returns a pointer to the last extension (e.g. the position of the last period).
* Returns a pointer to the nil byte when no extension is found.
*/
const char *BLI_path_extension_or_end(const char *filepath)
ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL;
/**
* Returns a pointer to the last extension (e.g. the position of the last period).
* Returns NULL if there is no extension.
@ -416,7 +422,7 @@ bool BLI_path_frame_get(const char *path, int *r_frame, int *r_digits_len) ATTR_
* So: `/some/path_123.jpeg`
* Becomes: `/some/path_###` with `r_ext` set to `.jpeg`.
*/
void BLI_path_frame_strip(char *path, char *r_ext) ATTR_NONNULL();
void BLI_path_frame_strip(char *path, char *r_ext, size_t ext_maxlen) ATTR_NONNULL();
/**
* Check if we have '#' chars, usable for #BLI_path_frame, #BLI_path_frame_range
*/

View File

@ -59,9 +59,9 @@ int BLI_path_sequence_decode(const char *string, char *head, char *tail, ushort
int i;
bool found_digit = false;
const char *const lslash = BLI_path_slash_rfind(string);
const char *const extension = BLI_path_extension(lslash ? lslash : string);
const char *const extension = BLI_path_extension_or_end(lslash ? lslash : string);
const uint lslash_len = lslash != NULL ? (int)(lslash - string) : 0;
const uint name_end = extension != NULL ? (int)((extension - string)) : strlen(string);
const uint name_end = (uint)(extension - string);
for (i = name_end - 1; i >= (int)lslash_len; i--) {
if (isdigit(string[i])) {
@ -587,17 +587,30 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char
#ifdef DEBUG_STRSIZE
memset(string, 0xff, sizeof(*string) * maxlen);
#endif
const size_t string_len = strlen(string);
const size_t suffix_len = strlen(suffix);
const size_t sep_len = strlen(sep);
const char *const extension = BLI_path_extension(string);
const size_t string_end = extension != NULL ? (int)((extension - string)) : string_len;
char extension_copy[FILE_MAX];
char *extension = (char *)BLI_path_extension_or_end(string);
const size_t extension_len = strlen(extension);
const size_t string_end = extension - string;
const size_t string_len = string_end + extension_len;
if (string_len + sep_len + suffix_len >= maxlen) {
return false;
}
BLI_strncpy(extension_copy, string + string_end, sizeof(extension));
BLI_sprintf(string + string_end, "%s%s%s", sep, suffix, extension_copy);
if (extension_len) {
memmove(extension + (sep_len + suffix_len), extension, extension_len);
}
char *c = string + string_end;
if (sep_len) {
memcpy(c, sep, sep_len);
c += sep_len;
}
if (suffix_len) {
memcpy(c, suffix, suffix_len);
c += suffix_len;
}
c += extension_len;
*c = '\0';
return true;
}
@ -750,9 +763,8 @@ bool BLI_path_frame_get(const char *path, int *r_frame, int *r_digits_len)
*r_digits_len = 0;
const char *file = BLI_path_basename(path);
const char *file_ext = BLI_path_extension(file);
const int file_len = strlen(file);
const char *c = file_ext ? file_ext : file + file_len;
const char *file_ext = BLI_path_extension_or_end(file);
const char *c = file_ext;
/* Find start of number (if there is one). */
int digits_len = 0;
@ -771,7 +783,7 @@ bool BLI_path_frame_get(const char *path, int *r_frame, int *r_digits_len)
return true;
}
void BLI_path_frame_strip(char *path, char *r_ext)
void BLI_path_frame_strip(char *path, char *r_ext, const size_t ext_maxlen)
{
*r_ext = '\0';
if (*path == '\0') {
@ -779,10 +791,8 @@ void BLI_path_frame_strip(char *path, char *r_ext)
}
char *file = (char *)BLI_path_basename(path);
char *file_ext = (char *)BLI_path_extension(file);
const int file_len = strlen(file);
char *c = file_ext ? file_ext : file + file_len;
char *suffix = c;
char *file_ext = (char *)BLI_path_extension_or_end(file);
char *c = file_ext;
/* Find start of number (if there is one). */
int digits_len = 0;
@ -791,10 +801,9 @@ void BLI_path_frame_strip(char *path, char *r_ext)
}
c++;
int suffix_length = file_len - (suffix - file);
memcpy(r_ext, suffix, suffix_length + 1);
BLI_strncpy(r_ext, file_ext, ext_maxlen);
/* replace the number with the suffix and terminate the string */
/* Replace the number with the suffix and terminate the string. */
while (digits_len--) {
*c++ = '#';
}
@ -1264,11 +1273,7 @@ bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext)
#ifdef DEBUG_STRSIZE
memset(path, 0xff, sizeof(*path) * maxlen);
#endif
char *path_ext = (char *)BLI_path_extension(path);
if (path_ext == NULL) {
path_ext = path + strlen(path);
}
char *path_ext = (char *)BLI_path_extension_or_end(path);
const size_t ext_len = strlen(ext);
if ((path_ext - path) + ext_len >= maxlen) {
return false;
@ -1293,20 +1298,32 @@ bool BLI_path_extension_ensure(char *path, size_t maxlen, const char *ext)
#ifdef DEBUG_STRSIZE
memset(path, 0xff, sizeof(*path) * maxlen);
#endif
char *path_ext = (char *)BLI_path_extension(path);
if (path_ext == NULL) {
path_ext = path + strlen(path);
}
/* First check the extension is already there.
* If `path_ext` is the end of the string this is simply checking if `ext` is also empty. */
const char *path_ext = BLI_path_extension_or_end(path);
if (STREQ(path_ext, ext)) {
return true;
}
const size_t path_len = strlen(path);
const size_t ext_len = strlen(ext);
if ((path_ext - path) + ext_len >= maxlen) {
ssize_t a;
for (a = path_len - 1; a >= 0; a--) {
if (path[a] == '.') {
path[a] = '\0';
}
else {
break;
}
}
a++;
if (a + ext_len >= maxlen) {
return false;
}
memcpy(path_ext, ext, ext_len + 1);
memcpy(path + a, ext, ext_len + 1);
return true;
}
@ -1358,7 +1375,7 @@ void BLI_split_file_part(const char *string, char *file, const size_t filelen)
BLI_split_dirfile(string, NULL, file, 0, filelen);
}
const char *BLI_path_extension(const char *filepath)
const char *BLI_path_extension_or_end(const char *filepath)
{
/* NOTE(@ideasman42): Skip the extension when there are no preceding non-extension characters in
* the file name. This ignores extensions at the beginning of a string or directly after a slash.
@ -1367,7 +1384,8 @@ const char *BLI_path_extension(const char *filepath)
* Matches Python's `os.path.splitext`. */
const char *ext = NULL;
bool has_non_ext = false;
for (const char *c = filepath; *c; c++) {
const char *c = filepath;
for (; *c; c++) {
switch (*c) {
case '.': {
if (has_non_ext) {
@ -1387,7 +1405,17 @@ const char *BLI_path_extension(const char *filepath)
}
}
}
return ext;
if (ext) {
return ext;
}
BLI_assert(*c == '\0');
return c;
}
const char *BLI_path_extension(const char *filepath)
{
const char *ext = BLI_path_extension_or_end(filepath);
return *ext ? ext : NULL;
}
size_t BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__restrict file)

View File

@ -42,7 +42,7 @@ static char *str_replace_char_strdup(const char *str, char src, char dst)
/** \name Tests for: #BLI_path_normalize
* \{ */
#define NORMALIZE_WITH_BASEDIR(input, input_base, output) \
#define NORMALIZE_WITH_BASEDIR(input, input_base, output_expect) \
{ \
char path[FILE_MAX] = input; \
const char *input_base_test = input_base; \
@ -57,11 +57,11 @@ static char *str_replace_char_strdup(const char *str, char src, char dst)
free((void *)input_base_test); \
} \
} \
EXPECT_STREQ(output, path); \
EXPECT_STREQ(path, output_expect); \
} \
((void)0)
#define NORMALIZE(input, output) NORMALIZE_WITH_BASEDIR(input, nullptr, output)
#define NORMALIZE(input, output_expect) NORMALIZE_WITH_BASEDIR(input, nullptr, output_expect)
/* #BLI_path_normalize: "/./" -> "/" */
TEST(path_util, Clean_Dot)
@ -102,7 +102,7 @@ TEST(path_util, Clean_Parent)
/** \name Tests for: #BLI_path_parent_dir
* \{ */
#define PARENT_DIR(input, output) \
#define PARENT_DIR(input, output_expect) \
{ \
char path[FILE_MAX] = input; \
if (SEP == '\\') { \
@ -112,7 +112,7 @@ TEST(path_util, Clean_Parent)
if (SEP == '\\') { \
BLI_str_replace_char(path, '\\', '/'); \
} \
EXPECT_STREQ(output, path); \
EXPECT_STREQ(path, output_expect); \
} \
((void)0)
@ -177,7 +177,7 @@ TEST(path_util, ParentDir_Complex)
} \
else { \
EXPECT_TRUE(ret); \
EXPECT_EQ(strlen(expect), len_output); \
EXPECT_EQ(len_output, strlen(expect)); \
path[index_output + len_output] = '\0'; \
EXPECT_STREQ(&path[index_output], expect); \
} \
@ -515,42 +515,42 @@ TEST(path_util, Frame)
char path[FILE_MAX] = "";
ret = BLI_path_frame(path, 123, 1);
EXPECT_TRUE(ret);
EXPECT_STREQ("123", path);
EXPECT_STREQ(path, "123");
}
{
char path[FILE_MAX] = "";
ret = BLI_path_frame(path, 123, 12);
EXPECT_TRUE(ret);
EXPECT_STREQ("000000000123", path);
EXPECT_STREQ(path, "000000000123");
}
{
char path[FILE_MAX] = "test_";
ret = BLI_path_frame(path, 123, 1);
EXPECT_TRUE(ret);
EXPECT_STREQ("test_123", path);
EXPECT_STREQ(path, "test_123");
}
{
char path[FILE_MAX] = "test_";
ret = BLI_path_frame(path, 1, 12);
EXPECT_TRUE(ret);
EXPECT_STREQ("test_000000000001", path);
EXPECT_STREQ(path, "test_000000000001");
}
{
char path[FILE_MAX] = "test_############";
ret = BLI_path_frame(path, 1, 0);
EXPECT_TRUE(ret);
EXPECT_STREQ("test_000000000001", path);
EXPECT_STREQ(path, "test_000000000001");
}
{
char path[FILE_MAX] = "test_#_#_middle";
ret = BLI_path_frame(path, 123, 0);
EXPECT_TRUE(ret);
EXPECT_STREQ("test_#_123_middle", path);
EXPECT_STREQ(path, "test_#_123_middle");
}
/* intentionally fail */
@ -558,14 +558,14 @@ TEST(path_util, Frame)
char path[FILE_MAX] = "";
ret = BLI_path_frame(path, 123, 0);
EXPECT_FALSE(ret);
EXPECT_STREQ("", path);
EXPECT_STREQ(path, "");
}
{
char path[FILE_MAX] = "test_middle";
ret = BLI_path_frame(path, 123, 0);
EXPECT_FALSE(ret);
EXPECT_STREQ("test_middle", path);
EXPECT_STREQ(path, "test_middle");
}
/* negative frame numbers */
@ -573,13 +573,13 @@ TEST(path_util, Frame)
char path[FILE_MAX] = "test_####";
ret = BLI_path_frame(path, -1, 4);
EXPECT_TRUE(ret);
EXPECT_STREQ("test_-0001", path);
EXPECT_STREQ(path, "test_-0001");
}
{
char path[FILE_MAX] = "test_####";
ret = BLI_path_frame(path, -100, 4);
EXPECT_TRUE(ret);
EXPECT_STREQ("test_-0100", path);
EXPECT_STREQ(path, "test_-0100");
}
}
@ -595,52 +595,52 @@ TEST(path_util, SplitDirfile)
const char *path = "";
char dir[FILE_MAX], file[FILE_MAX];
BLI_split_dirfile(path, dir, file, sizeof(dir), sizeof(file));
EXPECT_STREQ("", dir);
EXPECT_STREQ("", file);
EXPECT_STREQ(dir, "");
EXPECT_STREQ(file, "");
}
{
const char *path = "/";
char dir[FILE_MAX], file[FILE_MAX];
BLI_split_dirfile(path, dir, file, sizeof(dir), sizeof(file));
EXPECT_STREQ("/", dir);
EXPECT_STREQ("", file);
EXPECT_STREQ(dir, "/");
EXPECT_STREQ(file, "");
}
{
const char *path = "fileonly";
char dir[FILE_MAX], file[FILE_MAX];
BLI_split_dirfile(path, dir, file, sizeof(dir), sizeof(file));
EXPECT_STREQ("", dir);
EXPECT_STREQ("fileonly", file);
EXPECT_STREQ(dir, "");
EXPECT_STREQ(file, "fileonly");
}
{
const char *path = "dironly/";
char dir[FILE_MAX], file[FILE_MAX];
BLI_split_dirfile(path, dir, file, sizeof(dir), sizeof(file));
EXPECT_STREQ("dironly/", dir);
EXPECT_STREQ("", file);
EXPECT_STREQ(dir, "dironly/");
EXPECT_STREQ(file, "");
}
{
const char *path = "/a/b";
char dir[FILE_MAX], file[FILE_MAX];
BLI_split_dirfile(path, dir, file, sizeof(dir), sizeof(file));
EXPECT_STREQ("/a/", dir);
EXPECT_STREQ("b", file);
EXPECT_STREQ(dir, "/a/");
EXPECT_STREQ(file, "b");
}
{
const char *path = "/dirtoobig/filetoobig";
char dir[5], file[5];
BLI_split_dirfile(path, dir, file, sizeof(dir), sizeof(file));
EXPECT_STREQ("/dir", dir);
EXPECT_STREQ("file", file);
EXPECT_STREQ(dir, "/dir");
EXPECT_STREQ(file, "file");
BLI_split_dirfile(path, dir, file, 1, 1);
EXPECT_STREQ("", dir);
EXPECT_STREQ("", file);
EXPECT_STREQ(dir, "");
EXPECT_STREQ(file, "");
}
}
@ -655,13 +655,13 @@ TEST(path_util, SplitDirfile)
char path[FILE_MAX]; \
char ext[FILE_MAX]; \
BLI_strncpy(path, (input_path), FILE_MAX); \
BLI_path_frame_strip(path, ext); \
BLI_path_frame_strip(path, ext, sizeof(ext)); \
EXPECT_STREQ(path, expect_path); \
EXPECT_STREQ(ext, expect_ext); \
} \
((void)0)
TEST(path_util, PathFrameStrip)
TEST(path_util, FrameStrip)
{
PATH_FRAME_STRIP("", "", "");
PATH_FRAME_STRIP("nonum.abc", "nonum", ".abc");
@ -674,6 +674,37 @@ TEST(path_util, PathFrameStrip)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Tests for: #BLI_path_extension
* \{ */
TEST(path_util, Extension)
{
EXPECT_EQ(BLI_path_extension("some.def/file"), nullptr);
EXPECT_EQ(BLI_path_extension("Text"), nullptr);
EXPECT_EQ(BLI_path_extension("Text…001"), nullptr);
EXPECT_EQ(BLI_path_extension(".hidden"), nullptr);
EXPECT_EQ(BLI_path_extension(".hidden/"), nullptr);
EXPECT_EQ(BLI_path_extension("/.hidden"), nullptr);
EXPECT_EQ(BLI_path_extension("dir/.hidden"), nullptr);
EXPECT_EQ(BLI_path_extension("/dir/.hidden"), nullptr);
EXPECT_EQ(BLI_path_extension("."), nullptr);
EXPECT_EQ(BLI_path_extension(".."), nullptr);
EXPECT_EQ(BLI_path_extension("..."), nullptr);
EXPECT_STREQ(BLI_path_extension("...a."), ".");
EXPECT_STREQ(BLI_path_extension("...a.."), ".");
EXPECT_EQ(BLI_path_extension("...a../"), nullptr);
EXPECT_STREQ(BLI_path_extension("some/file."), ".");
EXPECT_STREQ(BLI_path_extension("some/file.tar.gz"), ".gz");
EXPECT_STREQ(BLI_path_extension("some.def/file.abc"), ".abc");
EXPECT_STREQ(BLI_path_extension("C:\\some.def\\file.abc"), ".abc");
EXPECT_STREQ(BLI_path_extension("Text.001"), ".001");
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Tests for: #BLI_path_extension_check
* \{ */
@ -690,7 +721,7 @@ TEST(path_util, PathFrameStrip)
} \
((void)0)
TEST(path_util, PathExtensionCheck)
TEST(path_util, ExtensionCheck)
{
PATH_EXTENSION_CHECK("a/b/c.exe", ".exe", ".exe");
PATH_EXTENSION_CHECK("correct/path/to/file.h", ".h", ".h");
@ -717,6 +748,142 @@ TEST(path_util, PathExtensionCheck)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Tests for: #BLI_path_extension_replace
* \{ */
#define PATH_EXTENSION_REPLACE_WITH_MAXLEN( \
input_path, input_ext, expect_result, expect_path, maxlen) \
{ \
BLI_assert(maxlen <= FILE_MAX); \
char path[FILE_MAX]; \
BLI_strncpy(path, input_path, sizeof(path)); \
const bool ret = BLI_path_extension_replace(path, maxlen, input_ext); \
if (expect_result) { \
EXPECT_TRUE(ret); \
} \
else { \
EXPECT_FALSE(ret); \
} \
EXPECT_STREQ(path, expect_path); \
} \
((void)0)
#define PATH_EXTENSION_REPLACE(input_path, input_ext, expect_result, expect_path) \
PATH_EXTENSION_REPLACE_WITH_MAXLEN(input_path, input_ext, expect_result, expect_path, FILE_MAX)
TEST(path_util, ExtensionReplace)
{
PATH_EXTENSION_REPLACE("test", ".txt", true, "test.txt");
PATH_EXTENSION_REPLACE("test.", ".txt", true, "test.txt");
/* Unlike #BLI_path_extension_ensure, excess '.' are not stripped. */
PATH_EXTENSION_REPLACE("test..", ".txt", true, "test..txt");
PATH_EXTENSION_REPLACE("test.txt", ".txt", true, "test.txt");
PATH_EXTENSION_REPLACE("test.ext", ".txt", true, "test.txt");
PATH_EXTENSION_REPLACE("test", "_txt", true, "test_txt");
PATH_EXTENSION_REPLACE("test.ext", "_txt", true, "test_txt");
PATH_EXTENSION_REPLACE("test", "", true, "test");
/* Same as #BLI_path_extension_strip. */
PATH_EXTENSION_REPLACE("test.txt", "", true, "test");
/* Empty strings. */
PATH_EXTENSION_REPLACE("test", "", true, "test");
PATH_EXTENSION_REPLACE("", "_txt", true, "_txt");
PATH_EXTENSION_REPLACE("", "", true, "");
/* Ensure leading '.' isn't treated as an extension. */
PATH_EXTENSION_REPLACE(".hidden", ".hidden", true, ".hidden.hidden");
PATH_EXTENSION_REPLACE("..hidden", ".hidden", true, "..hidden.hidden");
PATH_EXTENSION_REPLACE("._.hidden", ".hidden", true, "._.hidden");
}
TEST(path_util, ExtensionReplace_Overflow)
{
/* Small values. */
PATH_EXTENSION_REPLACE_WITH_MAXLEN("test", ".txt", false, "test", 0);
PATH_EXTENSION_REPLACE_WITH_MAXLEN("test", ".txt", false, "test", 1);
/* One under fails, and exactly enough space succeeds. */
PATH_EXTENSION_REPLACE_WITH_MAXLEN("test", ".txt", false, "test", 8);
PATH_EXTENSION_REPLACE_WITH_MAXLEN("test", ".txt", true, "test.txt", 9);
PATH_EXTENSION_REPLACE_WITH_MAXLEN("test.xx", ".txt", false, "test.xx", 8);
PATH_EXTENSION_REPLACE_WITH_MAXLEN("test.xx", ".txt", true, "test.txt", 9);
}
#undef PATH_EXTENSION_REPLACE
#undef PATH_EXTENSION_REPLACE_WITH_MAXLEN
/** \} */
/* -------------------------------------------------------------------- */
/** \name Tests for: #BLI_path_extension_ensure
* \{ */
#define PATH_EXTENSION_ENSURE_WITH_MAXLEN( \
input_path, input_ext, expect_result, expect_path, maxlen) \
{ \
BLI_assert(maxlen <= FILE_MAX); \
char path[FILE_MAX]; \
BLI_strncpy(path, input_path, sizeof(path)); \
const bool ret = BLI_path_extension_ensure(path, maxlen, input_ext); \
if (expect_result) { \
EXPECT_TRUE(ret); \
} \
else { \
EXPECT_FALSE(ret); \
} \
EXPECT_STREQ(path, expect_path); \
} \
((void)0)
#define PATH_EXTENSION_ENSURE(input_path, input_ext, expect_result, expect_path) \
PATH_EXTENSION_ENSURE_WITH_MAXLEN(input_path, input_ext, expect_result, expect_path, FILE_MAX)
TEST(path_util, ExtensionEnsure)
{
PATH_EXTENSION_ENSURE("test", ".txt", true, "test.txt");
PATH_EXTENSION_ENSURE("test.", ".txt", true, "test.txt");
PATH_EXTENSION_ENSURE("test..", ".txt", true, "test.txt");
PATH_EXTENSION_ENSURE("test.txt", ".txt", true, "test.txt");
PATH_EXTENSION_ENSURE("test.ext", ".txt", true, "test.ext.txt");
PATH_EXTENSION_ENSURE("test", "_txt", true, "test_txt");
PATH_EXTENSION_ENSURE("test.ext", "_txt", true, "test.ext_txt");
/* An empty string does nothing (unlike replace which strips). */
PATH_EXTENSION_ENSURE("test.txt", "", true, "test.txt");
/* Empty strings. */
PATH_EXTENSION_ENSURE("test", "", true, "test");
PATH_EXTENSION_ENSURE("", "_txt", true, "_txt");
PATH_EXTENSION_ENSURE("", "", true, "");
/* Ensure leading '.' isn't treated as an extension. */
PATH_EXTENSION_ENSURE(".hidden", ".hidden", true, ".hidden.hidden");
PATH_EXTENSION_ENSURE("..hidden", ".hidden", true, "..hidden.hidden");
PATH_EXTENSION_ENSURE("._.hidden", ".hidden", true, "._.hidden");
}
TEST(path_util, ExtensionEnsure_Overflow)
{
/* Small values. */
PATH_EXTENSION_ENSURE_WITH_MAXLEN("test", ".txt", false, "test", 0);
PATH_EXTENSION_ENSURE_WITH_MAXLEN("test", ".txt", false, "test", 1);
/* One under fails, and exactly enough space succeeds. */
PATH_EXTENSION_ENSURE_WITH_MAXLEN("test", ".txt", false, "test", 8);
PATH_EXTENSION_ENSURE_WITH_MAXLEN("test", ".txt", true, "test.txt", 9);
}
#undef PATH_EXTENSION_ENSURE
#undef PATH_EXTENSION_ENSURE_WITH_MAXLEN
/** \} */
/* -------------------------------------------------------------------- */
/** \name Tests for: #BLI_path_frame_check_chars
* \{ */
@ -733,7 +900,7 @@ TEST(path_util, PathExtensionCheck)
} \
((void)0)
TEST(path_util, PathFrameCheckChars)
TEST(path_util, FrameCheckChars)
{
PATH_FRAME_CHECK_CHARS("a#", true);
PATH_FRAME_CHECK_CHARS("aaaaa#", true);
@ -774,7 +941,7 @@ TEST(path_util, PathFrameCheckChars)
} \
((void)0)
TEST(path_util, PathFrameRange)
TEST(path_util, FrameRange)
{
int dummy = -1;
PATH_FRAME_RANGE("#", 1, 2, dummy, "1-2");
@ -812,7 +979,7 @@ TEST(path_util, PathFrameRange)
} \
((void)0)
TEST(path_util, PathFrameGet)
TEST(path_util, FrameGet)
{
PATH_FRAME_GET("001.avi", 1, 3, true);
PATH_FRAME_GET("0000299.ext", 299, 7, true);
@ -836,14 +1003,14 @@ TEST(path_util, PathFrameGet)
char tail[FILE_MAX]; \
ushort numdigits = 0; \
const int result = BLI_path_sequence_decode(path, head, tail, &numdigits); \
EXPECT_EQ(expect_result, result); \
EXPECT_STREQ(expect_head, head); \
EXPECT_STREQ(expect_tail, tail); \
EXPECT_EQ(expect_numdigits, numdigits); \
EXPECT_EQ(result, expect_result); \
EXPECT_STREQ(head, expect_head); \
EXPECT_STREQ(tail, expect_tail); \
EXPECT_EQ(numdigits, expect_numdigits); \
} \
(void)0;
TEST(path_util, PathSequenceDecode)
TEST(path_util, SequenceDecode)
{
/* Basic use. */
PATH_SEQ_DECODE("file_123.txt", 123, "file_", ".txt", 3);
@ -861,37 +1028,6 @@ TEST(path_util, PathSequenceDecode)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Tests for: #BLI_path_extension
* \{ */
TEST(path_util, PathExtension)
{
EXPECT_EQ(nullptr, BLI_path_extension("some.def/file"));
EXPECT_EQ(nullptr, BLI_path_extension("Text"));
EXPECT_EQ(nullptr, BLI_path_extension("Text…001"));
EXPECT_EQ(nullptr, BLI_path_extension(".hidden"));
EXPECT_EQ(nullptr, BLI_path_extension(".hidden/"));
EXPECT_EQ(nullptr, BLI_path_extension("/.hidden"));
EXPECT_EQ(nullptr, BLI_path_extension("dir/.hidden"));
EXPECT_EQ(nullptr, BLI_path_extension("/dir/.hidden"));
EXPECT_EQ(nullptr, BLI_path_extension("."));
EXPECT_EQ(nullptr, BLI_path_extension(".."));
EXPECT_EQ(nullptr, BLI_path_extension("..."));
EXPECT_STREQ(".", BLI_path_extension("...a."));
EXPECT_STREQ(".", BLI_path_extension("...a.."));
EXPECT_EQ(nullptr, BLI_path_extension("...a../"));
EXPECT_STREQ(".", BLI_path_extension("some/file."));
EXPECT_STREQ(".gz", BLI_path_extension("some/file.tar.gz"));
EXPECT_STREQ(".abc", BLI_path_extension("some.def/file.abc"));
EXPECT_STREQ(".abc", BLI_path_extension("C:\\some.def\\file.abc"));
EXPECT_STREQ(".001", BLI_path_extension("Text.001"));
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Tests for: #BLI_path_suffix
* \{ */
@ -900,12 +1036,12 @@ TEST(path_util, PathExtension)
{ \
char path[FILE_MAX] = path_literal; \
const bool result = BLI_path_suffix(path, path_literal_max, suffix, sep); \
EXPECT_EQ(expect_result, result); \
EXPECT_STREQ(expect_path, path); \
EXPECT_EQ(result, expect_result); \
EXPECT_STREQ(path, expect_path); \
} \
(void)0;
TEST(path_util, PathSuffix)
TEST(path_util, Suffix)
{
/* Extension. */
PATH_SUFFIX("file.txt", FILE_MAX, "_", "123", true, "file_123.txt");
@ -923,6 +1059,11 @@ TEST(path_util, PathSuffix)
PATH_SUFFIX("", FILE_MAX, "_", "123", true, "_123");
/* Empty input/output. */
PATH_SUFFIX("", FILE_MAX, "", "", true, "");
/* Long suffix. */
PATH_SUFFIX("file.txt", FILE_MAX, "_", "1234567890", true, "file_1234567890.txt");
/* Long extension. */
PATH_SUFFIX("file.txt1234567890", FILE_MAX, "_", "123", true, "file_123.txt1234567890");
}
#undef PATH_SUFFIX
@ -933,7 +1074,7 @@ TEST(path_util, PathSuffix)
/** \name Tests for: #BLI_path_rel
* \{ */
#define PATH_REL(abs_path, ref_path, rel_path) \
#define PATH_REL(abs_path, ref_path, rel_path_expect) \
{ \
char path[FILE_MAX]; \
const char *ref_path_test = ref_path; \
@ -947,7 +1088,7 @@ TEST(path_util, PathSuffix)
BLI_str_replace_char(path, '\\', '/'); \
free((void *)ref_path_test); \
} \
EXPECT_STREQ(rel_path, path); \
EXPECT_STREQ(path, rel_path_expect); \
} \
void(0)
@ -957,17 +1098,17 @@ TEST(path_util, PathSuffix)
# define ABS_PREFIX ""
#endif
TEST(path_util, PathRelPath_Simple)
TEST(path_util, RelPath_Simple)
{
PATH_REL(ABS_PREFIX "/foo/bar/blender.blend", ABS_PREFIX "/foo/bar/", "//blender.blend");
}
TEST(path_util, PathRelPath_SimpleSubdir)
TEST(path_util, RelPath_SimpleSubdir)
{
PATH_REL(ABS_PREFIX "/foo/bar/blender.blend", ABS_PREFIX "/foo/bar", "//bar/blender.blend");
}
TEST(path_util, PathRelPath_BufferOverflowRoot)
TEST(path_util, RelPath_BufferOverflowRoot)
{
char abs_path_in[FILE_MAX];
const char *abs_prefix = ABS_PREFIX "/";
@ -983,7 +1124,7 @@ TEST(path_util, PathRelPath_BufferOverflowRoot)
PATH_REL(abs_path_in, abs_prefix, abs_path_out);
}
TEST(path_util, PathRelPath_BufferOverflowSubdir)
TEST(path_util, RelPath_BufferOverflowSubdir)
{
char abs_path_in[FILE_MAX];
const char *ref_path_in = ABS_PREFIX "/foo/bar/";
@ -1009,7 +1150,7 @@ TEST(path_util, PathRelPath_BufferOverflowSubdir)
/** \name Tests for: #BLI_path_contains
* \{ */
TEST(path_util, PathContains)
TEST(path_util, Contains)
{
EXPECT_TRUE(BLI_path_contains("/some/path", "/some/path")) << "A path contains itself";
EXPECT_TRUE(BLI_path_contains("/some/path", "/some/path/inside"))
@ -1032,7 +1173,7 @@ TEST(path_util, PathContains)
}
#ifdef WIN32
TEST(path_util, PathContains_Windows_case_insensitive)
TEST(path_util, Contains_Windows_case_insensitive)
{
EXPECT_TRUE(BLI_path_contains("C:\\some\\path", "c:\\SOME\\path\\inside"))
<< "On Windows path comparison should ignore case";

View File

@ -98,6 +98,7 @@ static void gpu_stack_vector_from_socket(GPUNodeStack &stack, const bNodeSocket
return;
default:
BLI_assert_unreachable();
return;
}
}
case SOCK_VECTOR: {
@ -115,6 +116,7 @@ static void gpu_stack_vector_from_socket(GPUNodeStack &stack, const bNodeSocket
return;
default:
BLI_assert_unreachable();
return;
}
}
case SOCK_RGBA: {
@ -131,6 +133,7 @@ static void gpu_stack_vector_from_socket(GPUNodeStack &stack, const bNodeSocket
return;
default:
BLI_assert_unreachable();
return;
}
}
default:

View File

@ -84,6 +84,19 @@ RNAPathKey::RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop, RNAPoin
{
}
RNAPathKey::RNAPathKey(const PointerRNA &target_prop,
const char *rna_path_from_target_prop,
const RNAPointerSource source)
: id(target_prop.owner_id), source(source)
{
/* Try to resolve path. */
int index;
if (!RNA_path_resolve_full(&target_prop, rna_path_from_target_prop, &ptr, &prop, &index)) {
ptr = PointerRNA_NULL;
prop = nullptr;
}
}
string RNAPathKey::identifier() const
{
const char *id_name = (id) ? id->name : "<No ID>";

View File

@ -188,6 +188,9 @@ struct PersistentOperationKey : public OperationKey {
struct RNAPathKey {
RNAPathKey(ID *id, const char *path, RNAPointerSource source);
RNAPathKey(const PointerRNA &target_prop,
const char *rna_path_from_target_prop,
RNAPointerSource source);
RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop, RNAPointerSource source);
string identifier() const;

View File

@ -1807,7 +1807,7 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
add_relation(target_key, driver_key, "Target -> Driver");
}
else if (dtar->rna_path != nullptr && dtar->rna_path[0] != '\0') {
RNAPathKey variable_exit_key(target_id, dtar->rna_path, RNAPointerSource::EXIT);
RNAPathKey variable_exit_key(target_prop, dtar->rna_path, RNAPointerSource::EXIT);
if (RNA_pointer_is_null(&variable_exit_key.ptr)) {
continue;
}

View File

@ -725,7 +725,9 @@ static int gpencil_vertexmode_toggle_exec(bContext *C, wmOperator *op)
}
if (mode == OB_MODE_VERTEX_GPENCIL) {
/* Be sure we have brushes. */
/* Be sure we have brushes.
* Need Draw as well (used for Palettes). */
BKE_paint_ensure(ts, (Paint **)&ts->gp_paint);
BKE_paint_ensure(ts, (Paint **)&ts->gp_vertexpaint);
const bool reset_mode = (ts->gp_vertexpaint->paint.brush == NULL);

View File

@ -3156,7 +3156,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id);
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_MESH);
me_eval = BKE_mesh_copy_for_eval(me_eval, false);
me_eval = BKE_mesh_copy_for_eval(me_eval);
BKE_object_material_from_eval_data(bmain, newob, &me_eval->id);
Mesh *new_mesh = (Mesh *)newob->data;
BKE_mesh_nomain_to_mesh(me_eval, new_mesh, newob);
@ -3388,7 +3388,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
newob->type = OB_MESH;
if (const Mesh *mesh_eval = geometry.get_mesh_for_read()) {
BKE_mesh_nomain_to_mesh(BKE_mesh_copy_for_eval(mesh_eval, false), new_mesh, newob);
BKE_mesh_nomain_to_mesh(BKE_mesh_copy_for_eval(mesh_eval), new_mesh, newob);
BKE_object_material_from_eval_data(bmain, newob, &mesh_eval->id);
new_mesh->attributes_for_write().remove_anonymous();
}

View File

@ -1107,7 +1107,7 @@ static bool modifier_apply_obdata(
/* Copy the relevant information to the original. */
Main *bmain = DEG_get_bmain(depsgraph);
BKE_object_material_from_eval_data(bmain, ob, &pointcloud_eval->id);
BKE_pointcloud_nomain_to_pointcloud(pointcloud_eval, &points, true);
BKE_pointcloud_nomain_to_pointcloud(pointcloud_eval, &points);
}
else {
/* TODO: implement for volumes. */

View File

@ -778,7 +778,7 @@ static Mesh *remesh_symmetry_bisect(Mesh *mesh, eSymmetryAxes symmetry_axes)
mmd.tolerance = QUADRIFLOW_MIRROR_BISECT_TOLERANCE;
Mesh *mesh_bisect, *mesh_bisect_temp;
mesh_bisect = BKE_mesh_copy_for_eval(mesh, false);
mesh_bisect = BKE_mesh_copy_for_eval(mesh);
int axis;
float plane_co[3], plane_no[3];
@ -860,7 +860,7 @@ static void quadriflow_start_job(void *customdata, bool *stop, bool *do_update,
/* Run Quadriflow bisect operations on a copy of the mesh to keep the code readable without
* freeing the original ID */
bisect_mesh = BKE_mesh_copy_for_eval(mesh, false);
bisect_mesh = BKE_mesh_copy_for_eval(mesh);
/* Bisect the input mesh using the paint symmetry settings */
bisect_mesh = remesh_symmetry_bisect(bisect_mesh, qj->symmetry_axes);

View File

@ -1135,7 +1135,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
const int trim_totverts = tot_screen_points * 2;
const int trim_totpolys = (2 * (tot_screen_points - 2)) + (2 * tot_screen_points);
trim_operation->mesh = BKE_mesh_new_nomain(trim_totverts, 0, trim_totpolys * 3, trim_totpolys);
trim_operation->mesh = BKE_mesh_new_nomain(trim_totverts, 0, trim_totpolys, trim_totpolys * 3);
trim_operation->true_mesh_co = static_cast<float(*)[3]>(
MEM_malloc_arrayN(trim_totverts, sizeof(float[3]), "mesh orco"));

View File

@ -7,7 +7,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_edgehash.h"
#include "BLI_math.h"
#include "BLI_task.h"
@ -199,7 +198,6 @@ static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss,
struct BoundaryFloodFillData {
SculptBoundary *boundary;
GSet *included_verts;
EdgeSet *preview_edges;
PBVHVertRef last_visited_vertex;
};

View File

@ -148,8 +148,24 @@ static bool sculpt_expand_is_face_in_active_component(SculptSession *ss,
ExpandCache *expand_cache,
const int f)
{
const int vert = ss->corner_verts[ss->polys[f].start()];
return sculpt_expand_is_vert_in_active_component(ss, expand_cache, BKE_pbvh_make_vref(vert));
PBVHVertRef vertex;
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
vertex.i = ss->corner_verts[ss->polys[f].start()];
break;
case PBVH_GRIDS: {
const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
vertex.i = ss->polys[f].start() * key->grid_area;
break;
}
case PBVH_BMESH: {
vertex.i = reinterpret_cast<intptr_t>(ss->bm->ftable[f]->l_first->v);
break;
}
}
return sculpt_expand_is_vert_in_active_component(ss, expand_cache, vertex);
}
/**

View File

@ -1832,7 +1832,7 @@ static int file_external_operation_exec(bContext *C, wmOperator *op)
#endif
BKE_reportf(
op->reports, RPT_ERROR, "Failure to perform exernal file operation on \"%s\"", filepath);
op->reports, RPT_ERROR, "Failure to perform external file operation on \"%s\"", filepath);
WM_cursor_set(CTX_wm_window(C), WM_CURSOR_DEFAULT);
return OPERATOR_CANCELLED;
}
@ -1869,7 +1869,7 @@ void FILE_OT_external_operation(wmOperatorType *ot)
RNA_def_enum(ot->srna,
"operation",
file_external_operation,
0,
FILE_EXTERNAL_OPERATION_OPEN,
"Operation",
"Operation to perform on the file or path");
}

View File

@ -161,11 +161,14 @@ static void gather_add_node_operations(const bContext &C,
if (!(node_type->poll && node_type->poll(node_type, &node_tree, &disabled_hint))) {
continue;
}
if (!(node_type->add_ui_poll && node_type->add_ui_poll(&C))) {
continue;
}
if (!node_type->gather_add_node_search_ops) {
continue;
}
Vector<nodes::AddNodeInfo> info_items;
nodes::GatherAddNodeSearchParams params(*node_type, node_tree, info_items);
nodes::GatherAddNodeSearchParams params(C, *node_type, node_tree, info_items);
node_type->gather_add_node_search_ops(params);
for (nodes::AddNodeInfo &info : info_items) {
AddNodeItem item{};

View File

@ -288,6 +288,9 @@ static void gather_socket_link_operations(const bContext &C,
if (!(node_type->poll && node_type->poll(node_type, &node_tree, &disabled_hint))) {
continue;
}
if (!(node_type->add_ui_poll && node_type->add_ui_poll(&C))) {
continue;
}
if (StringRefNull(node_type->ui_name).endswith("(Legacy)")) {
continue;
}

View File

@ -1242,7 +1242,7 @@ void sequencer_image_seq_reserve_frames(
char ext[PATH_MAX];
char filename_stripped[PATH_MAX];
/* Strip the frame from filename and substitute with `#`. */
BLI_path_frame_strip(filename, ext);
BLI_path_frame_strip(filename, ext, sizeof(ext));
for (int i = 0; i < len; i++, se++) {
BLI_strncpy(filename_stripped, filename, sizeof(filename_stripped));

View File

@ -45,7 +45,7 @@ set(SRC
view3d_gizmo_navigate_type.c
view3d_gizmo_preselect.c
view3d_gizmo_preselect_type.cc
view3d_gizmo_ruler.c
view3d_gizmo_ruler.cc
view3d_gizmo_tool_generic.c
view3d_header.c
view3d_iterators.cc

View File

@ -6,6 +6,9 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_math_matrix.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@ -58,6 +61,13 @@
#include "BLF_api.h"
using blender::float2;
using blender::float2x2;
using blender::float3;
using blender::float3x2;
using blender::float3x3;
using blender::float4;
/**
* Supporting transform features could be removed if the actual transform system is used.
* Keep the option open since each transform feature is duplicating logic.
@ -115,7 +125,7 @@ enum {
struct RulerItem;
typedef struct RulerInfo {
struct RulerInfo {
struct RulerItem *item_active;
int flag;
int snap_flag;
@ -143,27 +153,26 @@ typedef struct RulerInfo {
wmGizmo *gizmo;
PropertyRNA *prop_prevpoint;
} snap_data;
} RulerInfo;
};
/* -------------------------------------------------------------------- */
/* Ruler Item (two or three points) */
typedef struct RulerItem {
struct RulerItem {
wmGizmo gz;
/** World-space coords, middle being optional. */
float co[3][3];
float3x3 co;
int flag;
int raycast_dir; /* RULER_DIRECTION_* */
} RulerItem;
};
typedef struct RulerInteraction {
struct RulerInteraction {
/* selected coord */
char co_index; /* 0 -> 2 */
float drag_start_co[3];
} RulerInteraction;
float3 drag_start_co;
};
/* -------------------------------------------------------------------- */
/** \name Internal Ruler Utilities
@ -173,16 +182,16 @@ static RulerItem *ruler_item_add(wmGizmoGroup *gzgroup)
{
/* could pass this as an arg */
const wmGizmoType *gzt_ruler = WM_gizmotype_find("VIEW3D_GT_ruler_item", true);
RulerItem *ruler_item = (RulerItem *)WM_gizmo_new_ptr(gzt_ruler, gzgroup, NULL);
RulerItem *ruler_item = (RulerItem *)WM_gizmo_new_ptr(gzt_ruler, gzgroup, nullptr);
WM_gizmo_set_flag(&ruler_item->gz, WM_GIZMO_DRAW_MODAL, true);
return ruler_item;
}
static void ruler_item_remove(bContext *C, wmGizmoGroup *gzgroup, RulerItem *ruler_item)
{
RulerInfo *ruler_info = gzgroup->customdata;
RulerInfo *ruler_info = static_cast<RulerInfo *>(gzgroup->customdata);
if (ruler_info->item_active == ruler_item) {
ruler_info->item_active = NULL;
ruler_info->item_active = nullptr;
}
WM_gizmo_unlink(&gzgroup->gizmos, gzgroup->parent_gzmap, &ruler_item->gz, C);
}
@ -222,10 +231,10 @@ static void ruler_item_as_string(
static bool view3d_ruler_pick(wmGizmoGroup *gzgroup,
RulerItem *ruler_item,
const float mval[2],
const float2 mval,
int *r_co_index)
{
RulerInfo *ruler_info = gzgroup->customdata;
RulerInfo *ruler_info = static_cast<RulerInfo *>(gzgroup->customdata);
ARegion *region = ruler_info->region;
bool found = false;
@ -233,7 +242,7 @@ static bool view3d_ruler_pick(wmGizmoGroup *gzgroup,
int co_index_best = -1;
{
float co_ss[3][2];
float3x2 co_ss;
float dist;
int j;
@ -250,10 +259,10 @@ static bool view3d_ruler_pick(wmGizmoGroup *gzgroup,
found = true;
{
const float dist_points[3] = {
len_squared_v2v2(co_ss[0], mval),
len_squared_v2v2(co_ss[1], mval),
len_squared_v2v2(co_ss[2], mval),
const float3 dist_points = {
blender::math::distance_squared(co_ss[0], mval),
blender::math::distance_squared(co_ss[1], mval),
blender::math::distance_squared(co_ss[2], mval),
};
if (min_fff(UNPACK3(dist_points)) < RULER_PICK_DIST_SQ) {
co_index_best = min_axis_v3(dist_points);
@ -271,9 +280,9 @@ static bool view3d_ruler_pick(wmGizmoGroup *gzgroup,
found = true;
{
const float dist_points[2] = {
len_squared_v2v2(co_ss[0], mval),
len_squared_v2v2(co_ss[2], mval),
const float2 dist_points = {
blender::math::distance_squared(co_ss[0], mval),
blender::math::distance_squared(co_ss[2], mval),
};
if (min_ff(UNPACK2(dist_points)) < RULER_PICK_DIST_SQ) {
co_index_best = (dist_points[0] < dist_points[1]) ? 0 : 2;
@ -316,9 +325,13 @@ static void ruler_state_set(RulerInfo *ruler_info, int state)
ruler_info->state = state;
}
static void view3d_ruler_item_project(RulerInfo *ruler_info, float r_co[3], const int xy[2])
static void view3d_ruler_item_project(RulerInfo *ruler_info, float3 &r_co, const int xy[2])
{
ED_view3d_win_to_3d_int(ruler_info->area->spacedata.first, ruler_info->region, r_co, xy, r_co);
ED_view3d_win_to_3d_int(static_cast<const View3D *>(ruler_info->area->spacedata.first),
ruler_info->region,
r_co,
xy,
r_co);
}
/**
@ -333,81 +346,77 @@ static bool view3d_ruler_item_mousemove(const bContext *C,
const bool do_snap)
{
wmGizmo *snap_gizmo = ruler_info->snap_data.gizmo;
const float eps_bias = 0.0002f;
constexpr float eps_bias = 0.0002f;
float dist_px = MVAL_MAX_PX_DIST * U.pixelsize; /* snap dist */
if (ruler_item) {
RulerInteraction *inter = ruler_item->gz.interaction_data;
float *co = ruler_item->co[inter->co_index];
RulerInteraction *inter = static_cast<RulerInteraction *>(ruler_item->gz.interaction_data);
float3 &co = ruler_item->co[inter->co_index];
/* restore the initial depth */
copy_v3_v3(co, inter->drag_start_co);
co = inter->drag_start_co;
view3d_ruler_item_project(ruler_info, co, mval);
if (do_thickness && inter->co_index != 1) {
Scene *scene = DEG_get_input_scene(depsgraph);
View3D *v3d = ruler_info->area->spacedata.first;
View3D *v3d = static_cast<View3D *>(ruler_info->area->spacedata.first);
SnapObjectContext *snap_context = ED_gizmotypes_snap_3d_context_ensure(scene, snap_gizmo);
const float mval_fl[2] = {UNPACK2(mval)};
float ray_normal[3];
float ray_start[3];
float *co_other;
const float2 mval_fl = {float(mval[0]), float(mval[1])};
float3 ray_normal;
float3 ray_start;
float3 &co_other = ruler_item->co[inter->co_index == 0 ? 2 : 0];
co_other = ruler_item->co[inter->co_index == 0 ? 2 : 0];
SnapObjectParams snap_object_params{};
snap_object_params.snap_target_select = SCE_SNAP_TARGET_ALL;
snap_object_params.edit_mode_type = SNAP_GEOM_CAGE;
if (ED_transform_snap_object_project_view3d(snap_context,
depsgraph,
ruler_info->region,
v3d,
SCE_SNAP_MODE_FACE_RAYCAST,
&(const struct SnapObjectParams){
.snap_target_select = SCE_SNAP_TARGET_ALL,
.edit_mode_type = SNAP_GEOM_CAGE,
},
NULL,
mval_fl,
NULL,
&dist_px,
co,
ray_normal)) {
negate_v3(ray_normal);
eSnapMode hit = ED_transform_snap_object_project_view3d(snap_context,
depsgraph,
ruler_info->region,
v3d,
SCE_SNAP_MODE_FACE_RAYCAST,
&snap_object_params,
nullptr,
mval_fl,
nullptr,
&dist_px,
co,
ray_normal);
if (hit) {
/* add some bias */
madd_v3_v3v3fl(ray_start, co, ray_normal, eps_bias);
ray_start = co - ray_normal * eps_bias;
ED_transform_snap_object_project_ray(snap_context,
depsgraph,
v3d,
&(const struct SnapObjectParams){
.snap_target_select = SCE_SNAP_TARGET_ALL,
.edit_mode_type = SNAP_GEOM_CAGE,
},
&snap_object_params,
ray_start,
ray_normal,
NULL,
-ray_normal,
nullptr,
co_other,
NULL);
nullptr);
}
}
else {
View3D *v3d = ruler_info->area->spacedata.first;
View3D *v3d = static_cast<View3D *>(ruler_info->area->spacedata.first);
if (do_snap) {
float *prev_point = NULL;
float3 *prev_point = nullptr;
BLI_assert(ED_gizmotypes_snap_3d_is_enabled(snap_gizmo));
if (inter->co_index != 1) {
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
prev_point = ruler_item->co[1];
prev_point = &ruler_item->co[1];
}
else if (inter->co_index == 0) {
prev_point = ruler_item->co[2];
prev_point = &ruler_item->co[2];
}
else {
prev_point = ruler_item->co[0];
prev_point = &ruler_item->co[0];
}
}
if (prev_point != NULL) {
if (prev_point != nullptr) {
RNA_property_float_set_array(
snap_gizmo->ptr, ruler_info->snap_data.prop_prevpoint, prev_point);
snap_gizmo->ptr, ruler_info->snap_data.prop_prevpoint, *prev_point);
}
ED_gizmotypes_snap_3d_data_get(C, snap_gizmo, co, NULL, NULL, NULL);
ED_gizmotypes_snap_3d_data_get(C, snap_gizmo, co, nullptr, nullptr, nullptr);
}
#ifdef USE_AXIS_CONSTRAINTS
@ -416,7 +425,7 @@ static bool view3d_ruler_item_mousemove(const bContext *C,
Scene *scene = DEG_get_input_scene(depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
RegionView3D *rv3d = ruler_info->region->regiondata;
RegionView3D *rv3d = static_cast<RegionView3D *>(ruler_info->region->regiondata);
BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(ob);
@ -429,13 +438,12 @@ static bool view3d_ruler_item_mousemove(const bContext *C,
}
const int pivot_point = scene->toolsettings->transform_pivot_point;
float mat[3][3];
float3x3 mat;
ED_transform_calc_orientation_from_type_ex(
scene, view_layer, v3d, rv3d, ob, obedit, orient_index, pivot_point, mat);
scene, view_layer, v3d, rv3d, ob, obedit, orient_index, pivot_point, mat.ptr());
invert_m3(mat);
mul_m3_m3_pre(ruler_item->co, mat);
ruler_item->co = blender::math::invert(mat) * ruler_item->co;
/* Loop through the axes and constrain the dragged point to the current constrained axis.
*/
@ -444,8 +452,7 @@ static bool view3d_ruler_item_mousemove(const bContext *C,
ruler_item->co[inter->co_index][i] = ruler_item->co[(inter->co_index == 0) ? 2 : 0][i];
}
}
invert_m3(mat);
mul_m3_m3_pre(ruler_item->co, mat);
ruler_item->co = mat * ruler_item->co;
}
#endif
}
@ -464,7 +471,7 @@ static bool view3d_ruler_item_mousemove(const bContext *C,
*/
static bool gizmo_ruler_check_for_operator(const wmGizmoGroup *gzgroup)
{
return gzgroup->customdata != NULL;
return gzgroup->customdata != nullptr;
}
/** \} */
@ -481,13 +488,13 @@ static bGPDlayer *view3d_ruler_layer_get(bGPdata *gpd)
return gpl;
}
}
return NULL;
return nullptr;
}
static RulerItem *gzgroup_ruler_item_first_get(wmGizmoGroup *gzgroup)
{
#ifndef NDEBUG
RulerInfo *ruler_info = gzgroup->customdata;
RulerInfo *ruler_info = static_cast<RulerInfo *>(gzgroup->customdata);
BLI_assert(gzgroup->gizmos.first == ruler_info->snap_data.gizmo);
#endif
return (RulerItem *)((wmGizmo *)gzgroup->gizmos.first)->next;
@ -508,13 +515,13 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup)
const char *ruler_name = RULER_ID;
bool changed = false;
if (scene->gpd == NULL) {
if (scene->gpd == nullptr) {
scene->gpd = BKE_gpencil_data_addnew(bmain, "Annotations");
}
gpd = scene->gpd;
gpl = view3d_ruler_layer_get(gpd);
if (gpl == NULL) {
if (gpl == nullptr) {
gpl = BKE_gpencil_layer_addnew(gpd, ruler_name, false, false);
copy_v4_v4(gpl->color, U.gpencil_new_layer_col);
gpl->thickness = 1;
@ -530,10 +537,11 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup)
int j;
/* allocate memory for a new stroke */
gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
gps = (bGPDstroke *)MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
gps->totpoints = 3;
pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
pt = gps->points = (bGPDspoint *)MEM_callocN(sizeof(bGPDspoint) * gps->totpoints,
"gp_stroke_points");
for (j = 0; j < 3; j++) {
copy_v3_v3(&pt->x, ruler_item->co[j]);
pt->pressure = 1.0f;
@ -543,7 +551,8 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup)
}
else {
gps->totpoints = 2;
pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
pt = gps->points = (bGPDspoint *)MEM_callocN(sizeof(bGPDspoint) * gps->totpoints,
"gp_stroke_points");
for (j = 0; j < 3; j += 2) {
copy_v3_v3(&pt->x, ruler_item->co[j]);
pt->pressure = 1.0f;
@ -578,10 +587,10 @@ static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *gzgroup)
gpf = BKE_gpencil_layer_frame_get(gpl, scene->r.cfra, GP_GETFRAME_USE_PREV);
if (gpf) {
bGPDstroke *gps;
for (gps = gpf->strokes.first; gps; gps = gps->next) {
for (gps = static_cast<bGPDstroke *>(gpf->strokes.first); gps; gps = gps->next) {
bGPDspoint *pt = gps->points;
int j;
RulerItem *ruler_item = NULL;
RulerItem *ruler_item = nullptr;
if (gps->totpoints == 3) {
ruler_item = ruler_item_add(gzgroup);
for (j = 0; j < 3; j++) {
@ -617,20 +626,19 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
{
Scene *scene = CTX_data_scene(C);
UnitSettings *unit = &scene->unit;
RulerInfo *ruler_info = gz->parent_gzgroup->customdata;
RulerInfo *ruler_info = static_cast<RulerInfo *>(gz->parent_gzgroup->customdata);
RulerItem *ruler_item = (RulerItem *)gz;
ARegion *region = ruler_info->region;
RegionView3D *rv3d = region->regiondata;
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
const float cap_size = 4.0f * UI_SCALE_FAC;
const float bg_margin = 4.0f * UI_SCALE_FAC;
const float arc_size = 64.0f * UI_SCALE_FAC;
#define ARC_STEPS 24
const int arc_steps = ARC_STEPS;
const float color_act[4] = {1.0f, 1.0f, 1.0f, 1.0f};
const float color_base[4] = {0.0f, 0.0f, 0.0f, 1.0f};
constexpr int arc_steps = 24;
const float4 color_act = {1.0f, 1.0f, 1.0f, 1.0f};
const float4 color_base = {0.0f, 0.0f, 0.0f, 1.0f};
uchar color_text[3];
uchar color_wire[3];
float color_back[4] = {1.0f, 1.0f, 1.0f, 0.5f};
float4 color_back = {1.0f, 1.0f, 1.0f, 0.5f};
/* Pixel Space. */
GPU_matrix_push_projection();
@ -650,13 +658,13 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
UI_GetThemeColor3ubv(TH_WIRE, color_wire);
/* Avoid white on white text. (TODO: Fix by using theme). */
if ((int)color_text[0] + (int)color_text[1] + (int)color_text[2] > 127 * 3 * 0.6f) {
if (int(color_text[0]) + int(color_text[1]) + int(color_text[2]) > 127 * 3 * 0.6f) {
copy_v3_fl(color_back, 0.0f);
}
const bool is_act = (ruler_info->item_active == ruler_item);
float dir_ruler[2];
float co_ss[3][2];
float2 dir_ruler;
float3x2 co_ss;
bool proj_ok[3];
int j;
@ -682,14 +690,14 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
float4 viewport_size(0.0f);
GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
immUniform1i("colors_len", 2); /* "advanced" mode */
const float *col = is_act ? color_act : color_base;
const float4 &col = is_act ? color_act : color_base;
immUniform4f("color", 0.67f, 0.67f, 0.67f, 1.0f);
immUniform4f("color2", col[0], col[1], col[2], col[3]);
immUniform4fv("color2", col);
immUniform1f("dash_width", 6.0f);
immUniform1f("udash_factor", 0.5f);
@ -707,37 +715,34 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
/* arc */
{
float dir_tmp[3];
float ar_coord[3];
float3 dir_tmp;
float3 ar_coord;
float dir_a[3];
float dir_b[3];
float quat[4];
float axis[3];
float3 dir_a;
float3 dir_b;
float4 quat;
float3 axis;
float angle;
const float px_scale = (ED_view3d_pixel_size_no_ui_scale(rv3d, ruler_item->co[1]) *
min_fff(arc_size,
len_v2v2(co_ss[0], co_ss[1]) / 2.0f,
len_v2v2(co_ss[2], co_ss[1]) / 2.0f));
blender::math::distance(co_ss[0], co_ss[1]) / 2.0f,
blender::math::distance(co_ss[2], co_ss[1]) / 2.0f));
sub_v3_v3v3(dir_a, ruler_item->co[0], ruler_item->co[1]);
sub_v3_v3v3(dir_b, ruler_item->co[2], ruler_item->co[1]);
normalize_v3(dir_a);
normalize_v3(dir_b);
cross_v3_v3v3(axis, dir_a, dir_b);
dir_a = blender::math::normalize(ruler_item->co[0] - ruler_item->co[1]);
dir_b = blender::math::normalize(ruler_item->co[2] - ruler_item->co[1]);
axis = blender::math::cross(dir_a, dir_b);
angle = angle_normalized_v3v3(dir_a, dir_b);
axis_angle_to_quat(quat, axis, angle / arc_steps);
copy_v3_v3(dir_tmp, dir_a);
dir_tmp = dir_a;
immUniformColor3ubv(color_wire);
immBegin(GPU_PRIM_LINE_STRIP, arc_steps + 1);
for (j = 0; j <= arc_steps; j++) {
madd_v3_v3v3fl(ar_coord, ruler_item->co[1], dir_tmp, px_scale);
ar_coord = ruler_item->co[1] + dir_tmp * px_scale;
mul_qt_v3(quat, dir_tmp);
immVertex3fv(shdr_pos_3d, ar_coord);
@ -758,7 +763,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
immUniform1i("colors_len", 2); /* "advanced" mode */
const float *col = is_act ? color_act : color_base;
immUniform4f("color", 0.67f, 0.67f, 0.67f, 1.0f);
immUniform4f("color2", col[0], col[1], col[2], col[3]);
immUniform4fv("color2", col);
immUniform1f("dash_width", 6.0f);
immUniform1f("udash_factor", 0.5f);
@ -784,19 +789,13 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
/* capping */
{
float rot_90_vec_a[2];
float rot_90_vec_b[2];
float cap[2];
float2 cap;
sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[1]);
rot_90_vec_a[0] = -dir_ruler[1];
rot_90_vec_a[1] = dir_ruler[0];
normalize_v2(rot_90_vec_a);
dir_ruler = co_ss[0] - co_ss[1];
float2 rot_90_vec_a = blender::math::normalize(float2{-dir_ruler[1], dir_ruler[0]});
sub_v2_v2v2(dir_ruler, co_ss[1], co_ss[2]);
rot_90_vec_b[0] = -dir_ruler[1];
rot_90_vec_b[1] = dir_ruler[0];
normalize_v2(rot_90_vec_b);
dir_ruler = co_ss[1] - co_ss[2];
float2 rot_90_vec_b = blender::math::normalize(float2{-dir_ruler[1], dir_ruler[0]});
GPU_blend(GPU_BLEND_ALPHA);
@ -820,16 +819,16 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
immBegin(GPU_PRIM_LINES, proj_ok[0] * 2 + proj_ok[2] * 2 + proj_ok[1] * 4);
if (proj_ok[0]) {
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
cap = co_ss[0] + rot_90_vec_a * cap_size;
immVertex2fv(shdr_pos_2d, cap);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size);
cap = co_ss[0] - rot_90_vec_a * cap_size;
immVertex2fv(shdr_pos_2d, cap);
}
if (proj_ok[2]) {
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size);
cap = co_ss[2] + rot_90_vec_b * cap_size;
immVertex2fv(shdr_pos_2d, cap);
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size);
cap = co_ss[2] - rot_90_vec_b * cap_size;
immVertex2fv(shdr_pos_2d, cap);
}
@ -849,7 +848,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
/* text */
char numstr[256];
float numstr_size[2];
float2 numstr_size;
float posit[2];
const int prec = 2; /* XXX, todo, make optional */
@ -885,14 +884,12 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
else {
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);
dir_ruler = co_ss[0] - co_ss[2];
/* capping */
{
float rot_90_vec[2] = {-dir_ruler[1], dir_ruler[0]};
float cap[2];
normalize_v2(rot_90_vec);
float2 rot_90_vec = blender::math::normalize(float2{-dir_ruler[1], dir_ruler[0]});
float2 cap;
GPU_blend(GPU_BLEND_ALPHA);
@ -902,16 +899,16 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
immBegin(GPU_PRIM_LINES, proj_ok[0] * 2 + proj_ok[2] * 2);
if (proj_ok[0]) {
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
cap = co_ss[0] + rot_90_vec * cap_size;
immVertex2fv(shdr_pos_2d, cap);
madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size);
cap = co_ss[0] - rot_90_vec * cap_size;
immVertex2fv(shdr_pos_2d, cap);
}
if (proj_ok[2]) {
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size);
cap = co_ss[2] + rot_90_vec * cap_size;
immVertex2fv(shdr_pos_2d, cap);
madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size);
cap = co_ss[2] - rot_90_vec * cap_size;
immVertex2fv(shdr_pos_2d, cap);
}
@ -923,19 +920,18 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
/* text */
char numstr[256];
float numstr_size[2];
float2 numstr_size;
const int prec = 6; /* XXX, todo, make optional */
float posit[2];
float2 posit;
ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);
mid_v2_v2v2(posit, co_ss[0], co_ss[2]);
posit = (co_ss[0] + co_ss[2]) / 2.0f;
/* center text */
posit[0] -= numstr_size[0] / 2.0f;
posit[1] -= numstr_size[1] / 2.0f;
posit -= numstr_size / 2.0f;
/* draw text (bg) */
if (proj_ok[0] && proj_ok[2]) {
@ -965,14 +961,12 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
GPU_matrix_pop();
GPU_matrix_pop_projection();
#undef ARC_STEPS
}
static int gizmo_ruler_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
static int gizmo_ruler_test_select(bContext *, wmGizmo *gz, const int mval[2])
{
RulerItem *ruler_item_pick = (RulerItem *)gz;
const float mval_fl[2] = {UNPACK2(mval)};
const float mval_fl[2] = {float(mval[0]), float(mval[1])};
int co_index;
/* select and drag */
@ -996,7 +990,7 @@ static int gizmo_ruler_modal(bContext *C,
{
bool do_draw = false;
int exit_code = OPERATOR_RUNNING_MODAL;
RulerInfo *ruler_info = gz->parent_gzgroup->customdata;
RulerInfo *ruler_info = static_cast<RulerInfo *>(gz->parent_gzgroup->customdata);
RulerItem *ruler_item = (RulerItem *)gz;
ARegion *region = CTX_wm_region(C);
bool do_cursor_update = (event->val == KM_RELEASE) || (event->type == MOUSEMOVE);
@ -1036,7 +1030,8 @@ static int gizmo_ruler_modal(bContext *C,
const bool do_snap = !(tweak_flag & WM_GIZMO_TWEAK_SNAP);
#else
/* Ensure snap is up to date. */
ED_gizmotypes_snap_3d_data_get(C, ruler_info->snap_data.gizmo, NULL, NULL, NULL, NULL);
ED_gizmotypes_snap_3d_data_get(
C, ruler_info->snap_data.gizmo, nullptr, nullptr, nullptr, nullptr);
const bool do_snap = ED_gizmotypes_snap_3d_is_enabled(ruler_info->snap_data.gizmo);
#endif
@ -1066,9 +1061,9 @@ static int gizmo_ruler_modal(bContext *C,
static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
{
wmGizmoGroup *gzgroup = gz->parent_gzgroup;
RulerInfo *ruler_info = gzgroup->customdata;
RulerInfo *ruler_info = static_cast<RulerInfo *>(gzgroup->customdata);
RulerItem *ruler_item_pick = (RulerItem *)gz;
RulerInteraction *inter = MEM_callocN(sizeof(RulerInteraction), __func__);
RulerInteraction *inter = (RulerInteraction *)MEM_callocN(sizeof(RulerInteraction), __func__);
gz->interaction_data = inter;
ARegion *region = ruler_info->region;
@ -1091,7 +1086,7 @@ static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
/* find the factor */
{
float co_ss[2][2];
float2x2 co_ss;
float fac;
ED_view3d_project_float_global(
@ -1102,8 +1097,8 @@ static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
fac = line_point_factor_v2(mval_fl, co_ss[0], co_ss[1]);
CLAMP(fac, 0.0f, 1.0f);
interp_v3_v3v3(
ruler_item_pick->co[1], ruler_item_pick->co[0], ruler_item_pick->co[2], fac);
ruler_item_pick->co[1] = blender::math::interpolate(
ruler_item_pick->co[0], ruler_item_pick->co[2], fac);
}
/* update the new location */
@ -1117,7 +1112,7 @@ static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
ruler_state_set(ruler_info, RULER_STATE_DRAG);
/* store the initial depth */
copy_v3_v3(inter->drag_start_co, ruler_item_pick->co[inter->co_index]);
inter->drag_start_co = ruler_item_pick->co[inter->co_index];
}
if (inter->co_index == 1) {
@ -1129,20 +1124,20 @@ static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
{
/* Set Snap prev point. */
float *prev_point;
float3 *prev_point;
if (ruler_item_pick->flag & RULERITEM_USE_ANGLE) {
prev_point = (inter->co_index != 1) ? ruler_item_pick->co[1] : NULL;
prev_point = (inter->co_index != 1) ? &ruler_item_pick->co[1] : nullptr;
}
else if (inter->co_index == 0) {
prev_point = ruler_item_pick->co[2];
prev_point = &ruler_item_pick->co[2];
}
else {
prev_point = ruler_item_pick->co[0];
prev_point = &ruler_item_pick->co[0];
}
if (prev_point) {
RNA_property_float_set_array(
ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint, prev_point);
ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint, *prev_point);
}
else {
RNA_property_unset(ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint);
@ -1157,7 +1152,7 @@ static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
static void gizmo_ruler_exit(bContext *C, wmGizmo *gz, const bool cancel)
{
wmGizmoGroup *gzgroup = gz->parent_gzgroup;
RulerInfo *ruler_info = gzgroup->customdata;
RulerInfo *ruler_info = static_cast<RulerInfo *>(gzgroup->customdata);
if (!cancel) {
if (ruler_info->state == RULER_STATE_DRAG) {
@ -1205,21 +1200,21 @@ void VIEW3D_GT_ruler_item(wmGizmoType *gzt)
static void WIDGETGROUP_ruler_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
RulerInfo *ruler_info = MEM_callocN(sizeof(RulerInfo), __func__);
RulerInfo *ruler_info = (RulerInfo *)MEM_callocN(sizeof(RulerInfo), __func__);
wmGizmo *gizmo;
{
/* The gizmo snap has to be the first gizmo. */
const wmGizmoType *gzt_snap;
gzt_snap = WM_gizmotype_find("GIZMO_GT_snap_3d", true);
gizmo = WM_gizmo_new_ptr(gzt_snap, gzgroup, NULL);
gizmo = WM_gizmo_new_ptr(gzt_snap, gzgroup, nullptr);
RNA_enum_set(gizmo->ptr, "snap_elements_force", SCE_SNAP_MODE_GEOM);
ED_gizmotypes_snap_3d_flag_set(gizmo, V3D_SNAPCURSOR_SNAP_EDIT_GEOM_CAGE);
WM_gizmo_set_color(gizmo, (float[4]){1.0f, 1.0f, 1.0f, 1.0f});
WM_gizmo_set_color(gizmo, blender::float4(1.0f));
wmOperatorType *ot = WM_operatortype_find("VIEW3D_OT_ruler_add", true);
WM_gizmo_operator_set(gizmo, 0, ot, NULL);
WM_gizmo_operator_set(gizmo, 0, ot, nullptr);
}
if (view3d_ruler_from_gpencil(C, gzgroup)) {
@ -1264,8 +1259,8 @@ void VIEW3D_GGT_ruler(wmGizmoGroupType *gzgt)
static bool view3d_ruler_poll(bContext *C)
{
bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C);
if ((tref_rt == NULL) || !STREQ(view3d_gzgt_ruler_id, tref_rt->gizmo_group) ||
CTX_wm_region_view3d(C) == NULL) {
if ((tref_rt == nullptr) || !STREQ(view3d_gzgt_ruler_id, tref_rt->gizmo_group) ||
CTX_wm_region_view3d(C) == nullptr) {
return false;
}
return true;
@ -1298,10 +1293,10 @@ static int view3d_ruler_add_invoke(bContext *C, wmOperator *op, const wmEvent *e
/* This is a little weak, but there is no real good way to tweak directly. */
WM_gizmo_highlight_set(gzmap, &ruler_item->gz);
if (WM_operator_name_call(
C, "GIZMOGROUP_OT_gizmo_tweak", WM_OP_INVOKE_REGION_WIN, NULL, event) ==
C, "GIZMOGROUP_OT_gizmo_tweak", WM_OP_INVOKE_REGION_WIN, nullptr, event) ==
OPERATOR_RUNNING_MODAL) {
RulerInfo *ruler_info = gzgroup->customdata;
RulerInteraction *inter = ruler_item->gz.interaction_data;
RulerInfo *ruler_info = static_cast<RulerInfo *>(gzgroup->customdata);
RulerInteraction *inter = static_cast<RulerInteraction *>(ruler_item->gz.interaction_data);
struct Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
inter->co_index = 0;
@ -1344,7 +1339,7 @@ void VIEW3D_OT_ruler_add(wmOperatorType *ot)
/** \name Remove Ruler Operator
* \{ */
static int view3d_ruler_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int view3d_ruler_remove_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
@ -1360,7 +1355,7 @@ static int view3d_ruler_remove_invoke(bContext *C, wmOperator *op, const wmEvent
if (!gizmo_ruler_check_for_operator(gzgroup)) {
return OPERATOR_CANCELLED;
}
RulerInfo *ruler_info = gzgroup->customdata;
RulerInfo *ruler_info = static_cast<RulerInfo *>(gzgroup->customdata);
if (ruler_info->item_active) {
RulerItem *ruler_item = ruler_info->item_active;
if ((ruler_item->flag & RULERITEM_USE_ANGLE) &&

View File

@ -25,7 +25,7 @@ bke::CurvesGeometry mesh_to_curve_convert(
const bke::AnonymousAttributePropagationInfo &propagation_info);
bke::CurvesGeometry create_curve_from_vert_indices(
const Mesh &mesh,
const bke::AttributeAccessor &mesh_attributes,
Span<int> vert_indices,
Span<int> curve_offsets,
IndexRange cyclic_curves,

View File

@ -1544,7 +1544,7 @@ static Mesh *create_merged_mesh(const Mesh &mesh,
const int result_npolys = src_polys.size() - weld_mesh.poly_kill_len + weld_mesh.wpoly_new_len;
Mesh *result = BKE_mesh_new_nomain_from_template(
&mesh, result_nverts, result_nedges, result_nloops, result_npolys);
&mesh, result_nverts, result_nedges, result_npolys, result_nloops);
MutableSpan<int2> dst_edges = result->edges_for_write();
MutableSpan<int> dst_poly_offsets = result->poly_offsets_for_write();
MutableSpan<int> dst_corner_verts = result->corner_verts_for_write();

View File

@ -400,7 +400,7 @@ Mesh *create_cuboid_mesh(const float3 &size,
{
const CuboidConfig config(size, verts_x, verts_y, verts_z);
Mesh *mesh = BKE_mesh_new_nomain(config.vertex_count, 0, config.loop_count, config.poly_count);
Mesh *mesh = BKE_mesh_new_nomain(config.vertex_count, 0, config.poly_count, config.loop_count);
MutableSpan<float3> positions = mesh->vert_positions_for_write();
MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
MutableSpan<int> corner_verts = mesh->corner_verts_for_write();

View File

@ -19,7 +19,7 @@
namespace blender::geometry {
bke::CurvesGeometry create_curve_from_vert_indices(
const Mesh &mesh,
const bke::AttributeAccessor &mesh_attributes,
const Span<int> vert_indices,
const Span<int> curve_offsets,
const IndexRange cyclic_curves,
@ -30,7 +30,6 @@ bke::CurvesGeometry create_curve_from_vert_indices(
curves.offsets_for_write().last() = vert_indices.size();
curves.fill_curve_types(CURVE_TYPE_POLY);
const bke::AttributeAccessor mesh_attributes = mesh.attributes();
bke::MutableAttributeAccessor curves_attributes = curves.attributes_for_write();
if (!cyclic_curves.is_empty()) {
@ -82,7 +81,7 @@ struct CurveFromEdgesOutput {
};
static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
Span<std::pair<int, int>> edges)
const Span<int2> edges)
{
Vector<int> vert_indices;
vert_indices.reserve(edges.size());
@ -90,9 +89,9 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
/* Compute the number of edges connecting to each vertex. */
Array<int> neighbor_count(verts_num, 0);
for (const std::pair<int, int> &edge : edges) {
neighbor_count[edge.first]++;
neighbor_count[edge.second]++;
for (const int2 &edge : edges) {
neighbor_count[edge[0]]++;
neighbor_count[edge[1]]++;
}
/* Compute an offset into the array of neighbor edges based on the counts. */
@ -108,8 +107,8 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
/* Calculate the indices of each vertex's neighboring edges. */
Array<int> neighbors(edges.size() * 2);
for (const int i : edges.index_range()) {
const int v1 = edges[i].first;
const int v2 = edges[i].second;
const int v1 = edges[i][0];
const int v2 = edges[i][1];
neighbors[neighbor_offsets[v1] + used_slots[v1]] = v2;
neighbors[neighbor_offsets[v2] + used_slots[v2]] = v1;
used_slots[v1]++;
@ -199,19 +198,17 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
return {std::move(vert_indices), std::move(curve_offsets), cyclic_curves};
}
/**
* Get a separate array of the indices for edges in a selection (a boolean attribute).
* This helps to make the above algorithm simpler by removing the need to check for selection
* in many places.
*/
static Vector<std::pair<int, int>> get_selected_edges(const Mesh &mesh, const IndexMask selection)
static bke::CurvesGeometry edges_to_curves_convert(
const Mesh &mesh,
const Span<int2> edges,
const bke::AnonymousAttributePropagationInfo &propagation_info)
{
Vector<std::pair<int, int>> selected_edges;
const Span<int2> edges = mesh.edges();
for (const int i : selection) {
selected_edges.append({edges[i][0], edges[i][1]});
}
return selected_edges;
CurveFromEdgesOutput output = edges_to_curve_point_indices(mesh.totvert, edges);
return create_curve_from_vert_indices(mesh.attributes(),
output.vert_indices,
output.curve_offsets,
output.cyclic_curves,
propagation_info);
}
bke::CurvesGeometry mesh_to_curve_convert(
@ -219,11 +216,13 @@ bke::CurvesGeometry mesh_to_curve_convert(
const IndexMask selection,
const bke::AnonymousAttributePropagationInfo &propagation_info)
{
Vector<std::pair<int, int>> selected_edges = get_selected_edges(mesh, selection);
CurveFromEdgesOutput output = edges_to_curve_point_indices(mesh.totvert, selected_edges);
return create_curve_from_vert_indices(
mesh, output.vert_indices, output.curve_offsets, output.cyclic_curves, propagation_info);
const Span<int2> edges = mesh.edges();
if (selection.size() == edges.size()) {
return edges_to_curves_convert(mesh, edges, propagation_info);
}
Array<int2> selected_edges(selection.size());
array_utils::gather(edges, selection, selected_edges.as_mutable_span());
return edges_to_curves_convert(mesh, selected_edges, propagation_info);
}
} // namespace blender::geometry

View File

@ -1081,7 +1081,7 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options,
const int tot_loops = last_task.start_indices.loop + last_mesh.totloop;
const int tot_poly = last_task.start_indices.poly + last_mesh.totpoly;
Mesh *dst_mesh = BKE_mesh_new_nomain(tot_vertices, tot_edges, tot_loops, tot_poly);
Mesh *dst_mesh = BKE_mesh_new_nomain(tot_vertices, tot_edges, tot_poly, tot_loops);
MeshComponent &dst_component = r_realized_geometry.get_component_for_write<MeshComponent>();
dst_component.replace(dst_mesh);
bke::MutableAttributeAccessor dst_attributes = dst_mesh->attributes_for_write();

View File

@ -723,7 +723,7 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
if (topology_changed(existing_mesh, sample_sel)) {
new_mesh = BKE_mesh_new_nomain_from_template(
existing_mesh, positions->size(), 0, face_indices->size(), face_counts->size());
existing_mesh, positions->size(), 0, face_counts->size(), face_indices->size());
settings.read_flag |= MOD_MESHSEQ_READ_ALL;
}

View File

@ -83,7 +83,7 @@ class MeshImporter : public MeshImporterBase {
struct Primitive {
int poly_index;
int *material_indices;
unsigned int totpoly;
uint totpoly;
};
typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive>> MaterialIdPrimitiveArrayMap;
/* crazy name! */
@ -94,7 +94,7 @@ class MeshImporter : public MeshImporterBase {
bool set_poly_indices(int *poly_verts,
int loop_index,
const unsigned int *indices,
const uint *indices,
int loop_count);
void set_face_uv(blender::float2 *mloopuv,
@ -140,9 +140,7 @@ class MeshImporter : public MeshImporterBase {
*/
static void mesh_add_edges(Mesh *mesh, int len);
unsigned int get_loose_edge_count(COLLADAFW::Mesh *mesh);
CustomData create_edge_custom_data(EdgeHash *eh);
uint get_loose_edge_count(COLLADAFW::Mesh *mesh);
/**
* Return the number of faces by summing up
@ -168,11 +166,11 @@ class MeshImporter : public MeshImporterBase {
* So this function MUST be called after read_faces() (see below)
*/
void read_lines(COLLADAFW::Mesh *mesh, Mesh *me);
unsigned int get_vertex_count(COLLADAFW::Polygons *mp, int index);
uint get_vertex_count(COLLADAFW::Polygons *mp, int index);
void get_vector(float v[3], COLLADAFW::MeshVertexData &arr, int i, int stride);
bool is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData &nor, int count);
bool is_flat_face(uint *nind, COLLADAFW::MeshVertexData &nor, int count);
/**
* Returns the list of Users of the given Mesh object.

View File

@ -203,21 +203,19 @@ void importer_main(Main *bmain,
}
/* Create mesh and do all prep work. */
Mesh *mesh = BKE_mesh_add(bmain, ob_name);
Mesh *mesh_in_main = BKE_mesh_add(bmain, ob_name);
BKE_view_layer_base_deselect_all(scene, view_layer);
LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
Object *obj = BKE_object_add_only_object(bmain, OB_MESH, ob_name);
BKE_mesh_assign_object(bmain, obj, mesh);
BKE_mesh_assign_object(bmain, obj, mesh_in_main);
BKE_collection_object_add(bmain, lc->collection, obj);
BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, obj);
BKE_view_layer_base_select_and_set_active(view_layer, base);
/* Stuff ply data into the mesh. */
Mesh *temp_val = convert_ply_to_mesh(*data, mesh, import_params);
if (import_params.merge_verts && temp_val != mesh) {
BKE_mesh_nomain_to_mesh(temp_val, mesh, obj);
}
Mesh *mesh = convert_ply_to_mesh(*data, import_params);
BKE_mesh_nomain_to_mesh(mesh, mesh_in_main, obj);
/* Object matrix and finishing up. */
float global_scale = import_params.global_scale;

View File

@ -7,6 +7,7 @@
#include "BKE_attribute.h"
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
@ -17,23 +18,18 @@
#include "ply_import_mesh.hh"
namespace blender::io::ply {
Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams &params)
Mesh *convert_ply_to_mesh(PlyData &data, const PLYImportParams &params)
{
Mesh *mesh = BKE_mesh_new_nomain(
data.vertices.size(), data.edges.size(), data.face_sizes.size(), data.face_vertices.size());
/* Add vertices to the mesh. */
mesh->totvert = int(data.vertices.size());
CustomData_add_layer_named(
&mesh->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, mesh->totvert, "position");
mesh->vert_positions_for_write().copy_from(data.vertices);
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
if (!data.edges.is_empty()) {
mesh->totedge = int(data.edges.size());
CustomData_add_layer_named(
&mesh->edata, CD_PROP_INT32_2D, CD_CONSTRUCT, mesh->totedge, ".edge_verts");
MutableSpan<int2> edges = mesh->edges_for_write();
for (int i = 0; i < mesh->totedge; i++) {
for (const int i : data.edges.index_range()) {
int32_t v1 = data.edges[i].first;
int32_t v2 = data.edges[i].second;
if (v1 >= mesh->totvert) {
@ -50,18 +46,12 @@ Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams &para
/* Add faces to the mesh. */
if (!data.face_sizes.is_empty()) {
/* Create poly and loop layers. */
mesh->totpoly = int(data.face_sizes.size());
mesh->totloop = int(data.face_vertices.size());
BKE_mesh_poly_offsets_ensure_alloc(mesh);
CustomData_add_layer_named(
&mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh->totloop, ".corner_vert");
MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
MutableSpan<int> corner_verts = mesh->corner_verts_for_write();
/* Fill in face data. */
uint32_t offset = 0;
for (int i = 0; i < mesh->totpoly; i++) {
for (const int i : data.face_sizes.index_range()) {
uint32_t size = data.face_sizes[i];
poly_offsets[i] = offset;
for (int j = 0; j < size; j++) {
@ -83,12 +73,12 @@ Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams &para
attributes.lookup_or_add_for_write_span<ColorGeometry4f>("Col", ATTR_DOMAIN_POINT);
if (params.vertex_colors == PLY_VERTEX_COLOR_SRGB) {
for (int i = 0; i < data.vertex_colors.size(); i++) {
for (const int i : data.vertex_colors.index_range()) {
srgb_to_linearrgb_v4(colors.span[i], data.vertex_colors[i]);
}
}
else {
for (int i = 0; i < data.vertex_colors.size(); i++) {
for (const int i : data.vertex_colors.index_range()) {
copy_v4_v4(colors.span[i], data.vertex_colors[i]);
}
}
@ -101,7 +91,7 @@ Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams &para
if (!data.uv_coordinates.is_empty()) {
bke::SpanAttributeWriter<float2> uv_map = attributes.lookup_or_add_for_write_only_span<float2>(
"UVMap", ATTR_DOMAIN_CORNER);
for (size_t i = 0; i < data.face_vertices.size(); i++) {
for (const int i : data.face_vertices.index_range()) {
uv_map.span[i] = data.uv_coordinates[data.face_vertices[i]];
}
uv_map.finish();
@ -116,17 +106,18 @@ Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams &para
mesh, reinterpret_cast<float(*)[3]>(data.vertex_normals.data()));
}
BKE_mesh_smooth_flag_set(mesh, false);
/* Merge all vertices on the same location. */
if (params.merge_verts) {
std::optional<Mesh *> return_value = blender::geometry::mesh_merge_by_distance_all(
std::optional<Mesh *> merged_mesh = blender::geometry::mesh_merge_by_distance_all(
*mesh, IndexMask(mesh->totvert), 0.0001f);
if (return_value.has_value()) {
mesh = return_value.value();
if (merged_mesh) {
BKE_id_free(nullptr, &mesh->id);
mesh = *merged_mesh;
}
}
BKE_mesh_smooth_flag_set(mesh, false);
return mesh;
}
} // namespace blender::io::ply

View File

@ -13,9 +13,8 @@ namespace blender::io::ply {
/**
* Converts the #PlyData data-structure to a mesh.
* \param data: The PLY data.
* \return The mesh that can be used inside blender.
* \return A new mesh that can be used inside blender.
*/
Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams &params);
Mesh *convert_ply_to_mesh(PlyData &data, const PLYImportParams &params);
} // namespace blender::io::ply

View File

@ -78,13 +78,9 @@ void importer_main(Main *bmain,
BLI_strncpy(ob_name, BLI_path_basename(import_params.filepath), FILE_MAX);
BLI_path_extension_strip(ob_name);
Mesh *mesh = nullptr;
if (is_ascii_stl) {
mesh = read_stl_ascii(import_params.filepath, bmain, ob_name, import_params.use_facet_normal);
}
else {
mesh = read_stl_binary(file, bmain, ob_name, import_params.use_facet_normal);
}
Mesh *mesh = is_ascii_stl ?
read_stl_ascii(import_params.filepath, import_params.use_facet_normal) :
read_stl_binary(file, import_params.use_facet_normal);
if (mesh == nullptr) {
fprintf(stderr, "STL Importer: Failed to import mesh '%s'\n", import_params.filepath);
@ -99,10 +95,12 @@ void importer_main(Main *bmain,
BKE_mesh_validate(mesh, verbose_validate, false);
}
Mesh *mesh_in_main = BKE_mesh_add(bmain, ob_name);
BKE_mesh_nomain_to_mesh(mesh, mesh_in_main, nullptr);
BKE_view_layer_base_deselect_all(scene, view_layer);
LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
Object *obj = BKE_object_add_only_object(bmain, OB_MESH, ob_name);
BKE_mesh_assign_object(bmain, obj, mesh);
BKE_mesh_assign_object(bmain, obj, mesh_in_main);
BKE_collection_object_add(bmain, lc->collection, obj);
BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, obj);

View File

@ -111,13 +111,13 @@ static inline void parse_float3(StringBuffer &buf, float out[3])
}
}
Mesh *read_stl_ascii(const char *filepath, Main *bmain, char *mesh_name, bool use_custom_normals)
Mesh *read_stl_ascii(const char *filepath, const bool use_custom_normals)
{
size_t buffer_len;
void *buffer = BLI_file_read_text_as_mem(filepath, 0, &buffer_len);
if (buffer == nullptr) {
fprintf(stderr, "STL Importer: cannot read from ASCII STL file: '%s'\n", filepath);
return BKE_mesh_add(bmain, mesh_name);
return nullptr;
}
BLI_SCOPED_DEFER([&]() { MEM_freeN(buffer); });
@ -154,7 +154,7 @@ Mesh *read_stl_ascii(const char *filepath, Main *bmain, char *mesh_name, bool us
}
}
return stl_mesh.to_mesh(bmain, mesh_name);
return stl_mesh.to_mesh();
}
} // namespace blender::io::stl

View File

@ -30,6 +30,6 @@
namespace blender::io::stl {
Mesh *read_stl_ascii(const char *filepath, Main *bmain, char *mesh_name, bool use_custom_normals);
Mesh *read_stl_ascii(const char *filepath, bool use_custom_normals);
} // namespace blender::io::stl

View File

@ -29,7 +29,7 @@ struct STLBinaryTriangle {
};
#pragma pack(pop)
Mesh *read_stl_binary(FILE *file, Main *bmain, char *mesh_name, bool use_custom_normals)
Mesh *read_stl_binary(FILE *file, const bool use_custom_normals)
{
const int chunk_size = 1024;
uint32_t num_tris = 0;
@ -40,7 +40,7 @@ Mesh *read_stl_binary(FILE *file, Main *bmain, char *mesh_name, bool use_custom_
}
if (num_tris == 0) {
return BKE_mesh_add(bmain, mesh_name);
return BKE_mesh_new_nomain(0, 0, 0, 0);
}
Array<STLBinaryTriangle> tris_buf(chunk_size);
@ -57,7 +57,7 @@ Mesh *read_stl_binary(FILE *file, Main *bmain, char *mesh_name, bool use_custom_
}
}
return stl_mesh.to_mesh(bmain, mesh_name);
return stl_mesh.to_mesh();
}
} // namespace blender::io::stl

View File

@ -26,6 +26,6 @@ namespace blender::io::stl {
const size_t BINARY_HEADER_SIZE = 80;
const size_t BINARY_STRIDE = 12 * 4 + 2;
Mesh *read_stl_binary(FILE *file, Main *bmain, char *mesh_name, bool use_custom_normals);
Mesh *read_stl_binary(FILE *file, bool use_custom_normals);
} // namespace blender::io::stl

View File

@ -10,6 +10,7 @@
#include "BKE_mesh.hh"
#include "BLI_array.hh"
#include "BLI_array_utils.hh"
#include "BLI_math_vector.h"
#include "BLI_math_vector.hh"
#include "BLI_task.hh"
@ -60,7 +61,7 @@ void STLMeshHelper::add_triangle(const float3 &a,
}
}
Mesh *STLMeshHelper::to_mesh(Main *bmain, char *mesh_name)
Mesh *STLMeshHelper::to_mesh()
{
if (degenerate_tris_num_ > 0) {
std::cout << "STL Importer: " << degenerate_tris_num_ << " degenerate triangles were removed"
@ -71,21 +72,10 @@ Mesh *STLMeshHelper::to_mesh(Main *bmain, char *mesh_name)
<< std::endl;
}
Mesh *mesh = BKE_mesh_add(bmain, mesh_name);
/* User count is already 1 here, but will be set later in #BKE_mesh_assign_object. */
id_us_min(&mesh->id);
Mesh *mesh = BKE_mesh_new_nomain(verts_.size(), 0, tris_.size(), tris_.size() * 3);
mesh->totvert = verts_.size();
CustomData_add_layer_named(
&mesh->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, mesh->totvert, "position");
mesh->vert_positions_for_write().copy_from(verts_);
mesh->totpoly = tris_.size();
mesh->totloop = tris_.size() * 3;
BKE_mesh_poly_offsets_ensure_alloc(mesh);
CustomData_add_layer_named(
&mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, mesh->totloop, ".corner_vert");
MutableSpan<int> poly_offsets = mesh->poly_offsets_for_write();
threading::parallel_for(poly_offsets.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
@ -93,14 +83,7 @@ Mesh *STLMeshHelper::to_mesh(Main *bmain, char *mesh_name)
}
});
MutableSpan<int> corner_verts = mesh->corner_verts_for_write();
threading::parallel_for(tris_.index_range(), 2048, [&](IndexRange tris_range) {
for (const int i : tris_range) {
corner_verts[3 * i] = tris_[i].v1;
corner_verts[3 * i + 1] = tris_[i].v2;
corner_verts[3 * i + 2] = tris_[i].v3;
}
});
array_utils::copy(tris_.as_span().cast<int>(), mesh->corner_verts_for_write());
/* NOTE: edges must be calculated first before setting custom normals. */
BKE_mesh_calc_edges(mesh, false, false);

View File

@ -65,7 +65,7 @@ class STLMeshHelper {
const float3 &b,
const float3 &c,
const float3 &custom_normal);
Mesh *to_mesh(Main *bmain, char *mesh_name);
Mesh *to_mesh();
};
} // namespace blender::io::stl

View File

@ -942,7 +942,7 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
if (topology_changed(existing_mesh, params.motion_sample_time)) {
new_mesh = true;
active_mesh = BKE_mesh_new_nomain_from_template(
existing_mesh, positions_.size(), 0, face_indices_.size(), face_counts_.size());
existing_mesh, positions_.size(), 0, face_counts_.size(), face_indices_.size());
for (pxr::TfToken token : uv_tokens) {
add_customdata_cb(active_mesh, token.GetText(), CD_PROP_FLOAT2);

View File

@ -179,7 +179,7 @@ Mesh *USDShapeReader::mesh_from_prim(Mesh *existing_mesh,
Mesh *active_mesh = nullptr;
if (!position_counts_match || !poly_counts_match) {
active_mesh = BKE_mesh_new_nomain_from_template(
existing_mesh, positions.size(), 0, face_indices.size(), face_counts.size());
existing_mesh, positions.size(), 0, face_counts.size(), face_indices.size());
}
else {
active_mesh = existing_mesh;

View File

@ -48,7 +48,7 @@ Object *MeshFromGeometry::create_mesh(Main *bmain,
const int64_t tot_face_elems{mesh_geometry_.face_elements_.size()};
const int64_t tot_loops{mesh_geometry_.total_loops_};
Mesh *mesh = BKE_mesh_new_nomain(tot_verts_object, tot_edges, tot_loops, tot_face_elems);
Mesh *mesh = BKE_mesh_new_nomain(tot_verts_object, tot_edges, tot_face_elems, tot_loops);
Object *obj = BKE_object_add_only_object(bmain, OB_MESH, ob_name.c_str());
obj->data = BKE_object_obdata_add_from_type(bmain, OB_MESH, ob_name.c_str());

View File

@ -99,7 +99,7 @@ TEST(obj_exporter_utils, append_negative_frame_to_filename)
char path_with_frame[FILE_MAX] = {0};
const bool ok = append_frame_to_filename(path_original, frame, path_with_frame);
EXPECT_TRUE(ok);
EXPECT_EQ_ARRAY(path_with_frame, path_truth, BLI_strlen_utf8(path_truth));
EXPECT_STREQ(path_with_frame, path_truth);
}
TEST(obj_exporter_utils, append_positive_frame_to_filename)
@ -110,7 +110,7 @@ TEST(obj_exporter_utils, append_positive_frame_to_filename)
char path_with_frame[FILE_MAX] = {0};
const bool ok = append_frame_to_filename(path_original, frame, path_with_frame);
EXPECT_TRUE(ok);
EXPECT_EQ_ARRAY(path_with_frame, path_truth, BLI_strlen_utf8(path_truth));
EXPECT_STREQ(path_with_frame, path_truth);
}
static std::string read_temp_file_in_string(const std::string &file_path)

View File

@ -602,6 +602,10 @@ enum {
CU_CHINFO_OVERFLOW = 1 << 6,
};
/** User adjustable as styles (not relating to run-time layout calculation). */
#define CU_CHINFO_STYLE_ALL \
(CU_CHINFO_BOLD | CU_CHINFO_ITALIC | CU_CHINFO_UNDERLINE | CU_CHINFO_SMALLCAPS)
/* mixed with KEY_LINEAR but define here since only curve supports */
#define KEY_CU_EASE 3

View File

@ -1496,8 +1496,8 @@ static void rna_SequenceTimelineChannel_name_set(PointerRNA *ptr, const char *va
sizeof(channel->name));
}
static void rna_SequenceTimelineChannel_mute_update(Main *UNUSED(bmain),
Scene *UNUSED(active_scene),
static void rna_SequenceTimelineChannel_mute_update(Main *bmain,
Scene *active_scene,
PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->owner_id;
@ -1516,6 +1516,8 @@ static void rna_SequenceTimelineChannel_mute_update(Main *UNUSED(bmain),
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
SEQ_relations_invalidate_cache_composite(scene, seq);
}
rna_Sequence_sound_update(bmain, active_scene, ptr);
}
static char *rna_SeqTimelineChannel_path(const PointerRNA *ptr)

View File

@ -551,7 +551,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
/* Initialize a result dm */
result = BKE_mesh_new_nomain_from_template(
mesh, result_nverts, result_nedges, result_nloops, result_npolys);
mesh, result_nverts, result_nedges, result_npolys, result_nloops);
float(*result_positions)[3] = BKE_mesh_vert_positions_for_write(result);
blender::MutableSpan<int2> result_edges = result->edges_for_write();
blender::MutableSpan<int> result_poly_offsets = result->poly_offsets_for_write();

View File

@ -189,7 +189,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* now we know the number of verts, edges and faces, we can create the mesh. */
result = BKE_mesh_new_nomain_from_template(
mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), loops_dst_num, faces_dst_num);
mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), faces_dst_num, loops_dst_num);
blender::MutableSpan<blender::int2> result_edges = result->edges_for_write();
blender::MutableSpan<int> result_poly_offsets = result->poly_offsets_for_write();
blender::MutableSpan<int> result_corner_verts = result->corner_verts_for_write();

View File

@ -702,8 +702,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext * /*ctx*/, M
Mesh *result = BKE_mesh_new_nomain_from_template(mesh,
verts_masked_num + verts_add_num,
edges_masked_num + edges_add_num,
loops_masked_num + loops_add_num,
polys_masked_num + polys_add_num);
polys_masked_num + polys_add_num,
loops_masked_num + loops_add_num);
copy_masked_verts_to_new_mesh(*mesh, *result, vertex_map);
if (use_interpolation) {

View File

@ -255,7 +255,7 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co
gogd.sx /= gogd.rx;
gogd.sy /= gogd.ry;
result = BKE_mesh_new_nomain(verts_num, 0, polys_num * 4, polys_num);
result = BKE_mesh_new_nomain(verts_num, 0, polys_num, polys_num * 4);
BKE_mesh_copy_parameters_for_eval(result, mesh_orig);
gogd.vert_positions = BKE_mesh_vert_positions_for_write(result);

View File

@ -312,7 +312,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
max_co = max[track];
}
result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, maxloop, maxpoly);
result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, maxpoly, maxloop);
const blender::OffsetIndices orig_polys = mesh->polys();
const blender::Span<int> orig_corner_verts = mesh->corner_verts();

View File

@ -154,7 +154,7 @@ static void deformVerts(ModifierData *md,
}
/* make new mesh */
psmd->mesh_final = BKE_mesh_copy_for_eval(mesh_src, false);
psmd->mesh_final = BKE_mesh_copy_for_eval(mesh_src);
BKE_mesh_vert_coords_apply(psmd->mesh_final, vertexCos);
BKE_mesh_tessface_ensure(psmd->mesh_final);
@ -185,7 +185,7 @@ static void deformVerts(ModifierData *md,
/* Make a persistent copy of the mesh. We don't actually need
* all this data, just some topology for remapping. Could be
* optimized once. */
psmd->mesh_original = BKE_mesh_copy_for_eval(mesh_original, false);
psmd->mesh_original = BKE_mesh_copy_for_eval(mesh_original);
}
BKE_mesh_tessface_ensure(psmd->mesh_original);

View File

@ -93,7 +93,7 @@ static void *dualcon_alloc_output(int totvert, int totquad)
return nullptr;
}
output->mesh = BKE_mesh_new_nomain(totvert, 0, 4 * totquad, totquad);
output->mesh = BKE_mesh_new_nomain(totvert, 0, totquad, 4 * totquad);
output->vert_positions = BKE_mesh_vert_positions_for_write(output->mesh);
output->poly_offsets = output->mesh->poly_offsets_for_write().data();
output->corner_verts = output->mesh->corner_verts_for_write().data();

View File

@ -390,7 +390,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
const bool do_remove_doubles = (ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f);
result = BKE_mesh_new_nomain_from_template(
mesh, int(maxVerts), int(maxEdges), int(maxPolys) * 4, int(maxPolys));
mesh, int(maxVerts), int(maxEdges), int(maxPolys), int(maxPolys) * 4);
/* The modifier doesn't support original index mapping on the edge or face domains. Remove
* original index layers, since otherwise edges aren't displayed at all in wireframe view. */
CustomData_free_layers(&result->edata, CD_ORIGINDEX, result->totedge);

View File

@ -321,8 +321,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
result = BKE_mesh_new_nomain_from_template(mesh,
int((verts_num * stride) + newVerts),
int((edges_num * stride) + newEdges + rimVerts),
int((loops_num * stride) + newLoops),
int((polys_num * stride) + newPolys));
int((polys_num * stride) + newPolys),
int((loops_num * stride) + newLoops));
float(*vert_positions)[3] = BKE_mesh_vert_positions_for_write(result);
blender::MutableSpan<blender::int2> edges = result->edges_for_write();

View File

@ -1982,7 +1982,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Create Mesh *result with proper capacity. */
result = BKE_mesh_new_nomain_from_template(
mesh, int(new_verts_num), int(new_edges_num), int(new_loops_num), int(new_polys_num));
mesh, int(new_verts_num), int(new_edges_num), int(new_polys_num), int(new_loops_num));
float(*vert_positions)[3] = BKE_mesh_vert_positions_for_write(result);
blender::MutableSpan<int2> edges = result->edges_for_write();

View File

@ -182,10 +182,8 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
/* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
* we really need a copy here. Maybe the CoW ob->data can be directly used. */
Mesh *mesh_prior_modifiers = BKE_object_get_pre_modified_mesh(ob);
mesh = (Mesh *)BKE_id_copy_ex(nullptr,
&mesh_prior_modifiers->id,
nullptr,
(LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_CD_REFERENCE));
mesh = (Mesh *)BKE_id_copy_ex(
nullptr, &mesh_prior_modifiers->id, nullptr, LIB_ID_COPY_LOCALIZE);
mesh->runtime->deformed_only = true;
}

View File

@ -25,18 +25,25 @@ struct AddNodeInfo {
};
class GatherAddNodeSearchParams {
const bContext &C_;
const bNodeType &node_type_;
const bNodeTree &node_tree_;
Vector<AddNodeInfo> &r_items;
public:
GatherAddNodeSearchParams(const bNodeType &node_type,
GatherAddNodeSearchParams(const bContext &C,
const bNodeType &node_type,
const bNodeTree &node_tree,
Vector<AddNodeInfo> &r_items)
: node_type_(node_type), node_tree_(node_tree), r_items(r_items)
: C_(C), node_type_(node_type), node_tree_(node_tree), r_items(r_items)
{
}
const bContext &context() const
{
return C_;
}
const bNodeTree &node_tree() const
{
return node_tree_;

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