Geometry Nodes: add simulation support #104924
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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>";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"));
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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{};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) &&
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ¶ms)
|
||||
Mesh *convert_ply_to_mesh(PlyData &data, const PLYImportParams ¶ms)
|
||||
{
|
||||
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 ¶
|
|||
|
||||
/* 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 ¶
|
|||
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 ¶
|
|||
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 ¶
|
|||
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
|
||||
|
|
|
@ -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 ¶ms);
|
||||
Mesh *convert_ply_to_mesh(PlyData &data, const PLYImportParams ¶ms);
|
||||
|
||||
} // namespace blender::io::ply
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue