Gizmo: press shift key to scale area lights uniformly #104418

Closed
Weizhen Huang wants to merge 13 commits from weizhen:shift_uniform_scale into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
99 changed files with 1461 additions and 807 deletions
Showing only changes of commit 67cb09357e - Show all commits

View File

@ -524,7 +524,7 @@ 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 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
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")
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
endif()

View File

@ -299,7 +299,11 @@ else
ifneq ("$(wildcard $(DEPS_BUILD_DIR)/build.ninja)","")
DEPS_BUILD_COMMAND:=ninja
else
DEPS_BUILD_COMMAND:=make -s
ifeq ($(OS), Darwin)
DEPS_BUILD_COMMAND:=make -s
else
DEPS_BUILD_COMMAND:="$(BLENDER_DIR)/build_files/build_environment/linux/make_deps_wrapper.sh" -s
endif
endif
endif
@ -398,7 +402,7 @@ endif
deps: .FORCE
@echo
@echo Configuring dependencies in \"$(DEPS_BUILD_DIR)\"
@echo Configuring dependencies in \"$(DEPS_BUILD_DIR)\", install to \"$(DEPS_INSTALL_DIR)\"
@cmake -H"$(DEPS_SOURCE_DIR)" \
-B"$(DEPS_BUILD_DIR)" \

View File

@ -0,0 +1,73 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0-or-later
# This script ensures:
# - One dependency is built at a time.
# - That dependency uses all available cores.
#
# Without this, simply calling `make -j$(nproc)` from the `${CMAKE_BUILD_DIR}/deps/`
# directory will build all projects at once.
#
# This is undesirable for the following reasons:
#
# - The output from many projects is mixed together,
# making it difficult to track down the cause of a build failure.
#
# - Larger dependencies such as LLVM can bottleneck the build process,
# making it necessary to cancel the build and manually run build commands in each directory.
#
# - Building many projects at once means canceling (Control-C) can lead to the build being in an undefined state.
# It's possible canceling happens as a patch is being applied or files are being copied.
# (steps that aren't part of the compilation process where it's typically safe to cancel).
if [[ -z "${MY_MAKE_CALL_LEVEL}" ]]; then
export MY_MAKE_CALL_LEVEL=0
export MY_MAKEFLAGS=$MAKEFLAGS
# Extract the jobs argument (`-jN`, `-j N`, `--jobs=N`).
add_next=0
for i in "$@"; do
case $i in
-j*)
MY_JOBS_ARG=$i
if [ "$MY_JOBS_ARG" = "-j" ]; then
add_next=1
fi
;;
--jobs=*)
shift # past argument=value
MY_JOBS_ARG=$i
;;
*)
if (( $add_next == 1 )); then
MY_JOBS_ARG="$MY_JOBS_ARG $i"
add_next=0
fi
;;
esac
done
unset i add_next
if [[ -z "${MY_JOBS_ARG}" ]]; then
export MY_JOBS_ARG="-j$(nproc)"
fi
# Support user defined `MAKEFLAGS`.
export MAKEFLAGS="$MY_MAKEFLAGS -j1"
else
export MY_MAKE_CALL_LEVEL=$(( $MY_MAKE_CALL_LEVEL + 1 ))
if (( $MY_MAKE_CALL_LEVEL == 1 )); then
# Important to set jobs to 1, otherwise user defined jobs argument is used.
export MAKEFLAGS="$MY_MAKEFLAGS -j1"
elif (( $MY_MAKE_CALL_LEVEL == 2 )); then
# This is the level used by each sub-project.
export MAKEFLAGS="$MY_MAKEFLAGS $MY_JOBS_ARG"
fi
# Else leave `MY_MAKEFLAGS` flags as-is, avoids setting a high number of jobs on recursive
# calls (which may easily run out of memory). Let the job-server handle the rest.
fi
# Useful for troubleshooting the wrapper.
# echo "Call level: $MY_MAKE_CALL_LEVEL, args=$@".
# Call actual make but ensure recursive calls run via this script.
exec make MAKE="$0" "$@"

View File

@ -487,7 +487,7 @@ BLENDER_VERSION_DOTS = "%d.%d" % (bpy.app.version[0], bpy.app.version[1])
if BLENDER_REVISION != "Unknown":
# SHA1 Git hash
BLENDER_VERSION_HASH = BLENDER_REVISION
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://developer.blender.org/rB%s>%s</a>" % (
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://projects.blender.org/blender/blender/commit/%s>%s</a>" % (
BLENDER_VERSION_HASH, BLENDER_VERSION_HASH,
)
BLENDER_VERSION_DATE = time.strftime("%d/%m/%Y", time.localtime(BLENDER_REVISION_TIMESTAMP))
@ -647,7 +647,7 @@ def undocumented_message(module_name, type_name, identifier):
module_name, type_name, identifier,
)
return "Undocumented, consider `contributing <https://developer.blender.org/T51061>`__."
return "Undocumented, consider `contributing <https://developer.blender.org/>`__."
def range_str(val):

View File

@ -1679,12 +1679,12 @@ class CyclesPreferences(bpy.types.AddonPreferences):
import sys
if sys.platform[:3] == "win":
driver_version = "21.Q4"
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
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"):
driver_version = "22.10"
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
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',
translate=False)
elif device_type == 'ONEAPI':

View File

@ -51,7 +51,7 @@ static inline bool hipSupportsDevice(const int hipDevId)
hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId);
hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId);
return (major >= 10);
return (major >= 9);
}
CCL_NAMESPACE_END

View File

@ -899,8 +899,8 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
/* Schedule samples equal to the resolution divider up to a maximum of 4.
* The idea is to have enough information on the screen by increasing the sample count as the
* resolution is decreased. */
/* NOTE: Changeing this formula will change the formula in
* "RenderScheduler::calculate_resolution_divider_for_time()"*/
/* NOTE: Changing this formula will change the formula in
* `RenderScheduler::calculate_resolution_divider_for_time()`. */
return min(max(1, resolution_divider / pixel_size_), 4);
}
@ -1177,18 +1177,18 @@ int RenderScheduler::calculate_resolution_divider_for_time(double desired_time,
{
const double ratio_between_times = actual_time / desired_time;
/* We can pass "ratio_between_times" to "get_num_samples_during_navigation()" to get our
/* We can pass `ratio_between_times` to `get_num_samples_during_navigation()` to get our
* navigation samples because the equation for calculating the resolution divider is as follows:
* "actual_time / desired_time = sqr(resolution_divider) / sample_count".
* While "resolution_divider" is less than or equal to 4, "resolution_divider = sample_count"
* (This relationship is determined in "get_num_samples_during_navigation()"). With some
* substitution we end up with "actual_time / desired_time = resolution_divider" while the
* `actual_time / desired_time = sqr(resolution_divider) / sample_count`.
* While `resolution_divider` is less than or equal to 4, `resolution_divider = sample_count`
* (This relationship is determined in `get_num_samples_during_navigation()`). With some
* substitution we end up with `actual_time / desired_time = resolution_divider` while the
* resolution divider is less than or equal to 4. Once the resolution divider increases above 4,
* the relationsip of "actual_time / desired_time = resolution_divider" is no longer true,
* however the sample count retrieved from "get_num_samples_during_navigation()" is still
* the relationship of `actual_time / desired_time = resolution_divider` is no longer true,
* however the sample count retrieved from `get_num_samples_during_navigation()` is still
* accurate if we continue using this assumption. It should be noted that the interaction between
* pixel_size, sample count, and resolution divider are automatically accounted for and that's
* why pixel_size isn't included in any of the equations. */
* `pixel_size`, sample count, and resolution divider are automatically accounted for and that's
* why `pixel_size` isn't included in any of the equations. */
const int navigation_samples = get_num_samples_during_navigation(
ceil_to_int(ratio_between_times));

View File

@ -412,11 +412,12 @@ if(WITH_CYCLES_CUDA_BINARIES)
# warn for other versions
if((CUDA_VERSION STREQUAL "101") OR
(CUDA_VERSION STREQUAL "102") OR
(CUDA_VERSION_MAJOR STREQUAL "11"))
(CUDA_VERSION_MAJOR STREQUAL "11") OR
(CUDA_VERSION_MAJOR STREQUAL "12"))
else()
message(WARNING
"CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
"build may succeed but only CUDA 11, 10.2 and 10.1 have been tested")
"build may succeed but only CUDA 12, 11, 10.2 and 10.1 have been tested")
endif()
# build for each arch
@ -514,6 +515,16 @@ if(WITH_CYCLES_CUDA_BINARIES)
else()
message(STATUS "CUDA binaries for ${arch} require CUDA 10 or earlier, skipped.")
endif()
elseif(${arch} MATCHES ".*_3.")
if(DEFINED CUDA11_NVCC_EXECUTABLE)
set(cuda_nvcc_executable ${CUDA11_NVCC_EXECUTABLE})
set(cuda_toolkit_root_dir ${CUDA11_TOOLKIT_ROOT_DIR})
elseif("${CUDA_VERSION}" LESS 120) # Support for sm_35, sm_37 was removed in CUDA 12
set(cuda_nvcc_executable ${CUDA_NVCC_EXECUTABLE})
set(cuda_toolkit_root_dir ${CUDA_TOOLKIT_ROOT_DIR})
else()
message(STATUS "CUDA binaries for ${arch} require CUDA 11 or earlier, skipped.")
endif()
elseif(${arch} MATCHES ".*_7." AND "${CUDA_VERSION}" LESS 100)
message(STATUS "CUDA binaries for ${arch} require CUDA 10.0+, skipped.")
elseif(${arch} MATCHES ".*_8.")

View File

@ -30,7 +30,7 @@ def url_prefill_from_blender(*, addon_info=None):
"**Blender Version**\n"
)
fh.write(
"Broken: version: %s, branch: %s, commit date: %s %s, hash: `rB%s`\n" % (
"Broken: version: %s, branch: %s, commit date: %s %s, hash: `%s`\n" % (
bpy.app.version_string,
bpy.app.build_branch.decode('utf-8', 'replace'),
bpy.app.build_commit_date.decode('utf-8', 'replace'),

View File

@ -991,6 +991,7 @@ url_manual_mapping = (
("bpy.types.geometrynodeinputmeshfacearea*", "modeling/geometry_nodes/mesh/read/face_area.html#bpy-types-geometrynodeinputmeshfacearea"),
("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/read/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"),
("bpy.types.geometrynodeinstancestopoints*", "modeling/geometry_nodes/instances/instances_to_points.html#bpy-types-geometrynodeinstancestopoints"),
("bpy.types.geometrynodematerialselection*", "modeling/geometry_nodes/material/material_selection.html#bpy-types-geometrynodematerialselection"),
("bpy.types.gpencillayer.viewlayer_render*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-viewlayer-render"),
("bpy.types.imagepaint.use_normal_falloff*", "sculpt_paint/brush/falloff.html#bpy-types-imagepaint-use-normal-falloff"),
("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"),
@ -2027,6 +2028,7 @@ url_manual_mapping = (
("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"),
("bpy.ops.mball.delete_metaelems*", "modeling/metas/editing.html#bpy-ops-mball-delete-metaelems"),
("bpy.ops.mball.reveal_metaelems*", "modeling/metas/properties.html#bpy-ops-mball-reveal-metaelems"),
("bpy.ops.mesh.bridge_edge_loops*", "modeling/meshes/editing/edge/bridge_edge_loops.html#bpy-ops-mesh-bridge-edge-loops"),
("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"),
("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"),
("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"),
@ -3021,6 +3023,7 @@ url_manual_mapping = (
("bpy.types.bakesettings*", "render/cycles/baking.html#bpy-types-bakesettings"),
("bpy.types.blendtexture*", "render/materials/legacy_textures/types/blend.html#bpy-types-blendtexture"),
("bpy.types.brush.height*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-height"),
("bpy.types.brush.jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-jitter"),
("bpy.types.castmodifier*", "modeling/modifiers/deform/cast.html#bpy-types-castmodifier"),
("bpy.types.curve.offset*", "modeling/curves/properties/geometry.html#bpy-types-curve-offset"),
("bpy.types.geometrynode*", "modeling/geometry_nodes/index.html#bpy-types-geometrynode"),

View File

@ -6345,9 +6345,8 @@ def km_node_link_modal_map(_params):
return keymap
# Fallback for gizmos that don't have custom a custom key-map.
def km_generic_gizmo(_params):
keymap = (
"Generic Gizmo",

View File

@ -1249,7 +1249,31 @@ class WM_OT_doc_view_manual(Operator):
# XXX, for some reason all RNA ID's are stored lowercase
# Adding case into all ID's isn't worth the hassle so force lowercase.
rna_id = rna_id.lower()
# NOTE: `fnmatch` in Python is slow as it translate the string to a regular-expression
# which needs to be compiled (as of Python 3.11), this is slow enough to cause a noticeable
# delay when opening manual links (approaching half a second).
#
# Resolve by matching characters that have a special meaning to `fnmatch`.
# The characters that can occur as the first special character are `*?[`.
# If any of these are used we must let `fnmatch` run its own matching logic.
# However, in most cases a literal prefix is used making it considerably faster
# to do a simple `startswith` check before performing a full match.
# An alternative solution could be to use `fnmatch` from C which is significantly
# faster than Python's, see !104581 for details.
import re
re_match_non_special = re.compile(r"^[^?\*\[]+").match
for pattern, url_suffix in url_mapping:
# Simple optimization, makes a big difference (over 50x speedup).
# Even when `non_special.end()` is zero (resulting in an empty-string),
# the `startswith` check succeeds so there is no need to check for an empty match.
non_special = re_match_non_special(pattern)
if non_special is None or not rna_id.startswith(pattern[:non_special.end()]):
continue
# End simple optimization.
if fnmatchcase(rna_id, pattern):
if verbose:
print(" match found: '%s' --> '%s'" % (pattern, url_suffix))

File diff suppressed because it is too large Load Diff

View File

@ -2319,21 +2319,15 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
bl_label = "New Features"
def draw(self, context):
self._draw_items(context,
(({"property": "use_sculpt_tools_tilt"},
("blender/blender/issues/82877",
"#82877")),
({"property": "use_extended_asset_browser"},
("blender/blender/projects/10",
"Pipeline, Assets & IO Project Page")),
({"property": "use_override_templates"},
("blender/blender/issues/73318",
"Milestone 4")),
({"property": "use_new_volume_nodes"},
("blender/blender/issues/103248",
"#103248")),
),
)
self._draw_items(
context, (
({"property": "use_sculpt_tools_tilt"}, ("blender/blender/issues/82877", "#82877")),
({"property": "use_extended_asset_browser"},
("blender/blender/projects/10", "Pipeline, Assets & IO Project Page")),
({"property": "use_override_templates"}, ("blender/blender/issues/73318", "Milestone 4")),
({"property": "use_new_volume_nodes"}, ("blender/blender/issues/103248", "#103248")),
),
)
class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):

View File

@ -137,6 +137,7 @@ bool CustomData_has_referenced(const struct CustomData *data);
* implemented for mloopuv/mloopcol, for now.
*/
void CustomData_data_copy_value(int type, const void *source, void *dest);
void CustomData_data_set_default_value(int type, void *elem);
/**
* Mixes the "value" (e.g. mloopuv uv or mloopcol colors) from one block into
@ -304,8 +305,8 @@ void CustomData_copy_data(const struct CustomData *source,
int source_index,
int dest_index,
int count);
void CustomData_copy_data_layer(const CustomData *source,
CustomData *dest,
void CustomData_copy_data_layer(const struct CustomData *source,
struct CustomData *dest,
int src_layer_index,
int dst_layer_index,
int src_index,
@ -444,7 +445,7 @@ void *CustomData_get_layer_named_for_write(CustomData *data,
int totelem);
int CustomData_get_offset(const struct CustomData *data, int type);
int CustomData_get_offset_named(const CustomData *data, int type, const char *name);
int CustomData_get_offset_named(const struct CustomData *data, int type, const char *name);
int CustomData_get_n_offset(const struct CustomData *data, int type, int n);
int CustomData_get_layer_index(const struct CustomData *data, int type);
@ -506,6 +507,8 @@ void CustomData_clear_layer_flag(struct CustomData *data, int type, int flag);
void CustomData_bmesh_set_default(struct CustomData *data, void **block);
void CustomData_bmesh_free_block(struct CustomData *data, void **block);
void CustomData_bmesh_alloc_block(struct CustomData *data, void **block);
/**
* Same as #CustomData_bmesh_free_block but zero the memory rather than freeing.
*/
@ -517,24 +520,6 @@ void CustomData_bmesh_free_block_data_exclude_by_type(struct CustomData *data,
void *block,
eCustomDataMask mask_exclude);
/**
* Copy custom data to/from layers as in mesh/derived-mesh, to edit-mesh
* blocks of data. the CustomData's must not be compatible.
*
* \param use_default_init: initializes data which can't be copied,
* typically you'll want to use this if the BM_xxx create function
* is called with BM_CREATE_SKIP_CD flag
*/
void CustomData_to_bmesh_block(const struct CustomData *source,
struct CustomData *dest,
int src_index,
void **dest_block,
bool use_default_init);
void CustomData_from_bmesh_block(const struct CustomData *source,
struct CustomData *dest,
void *src_block,
int dest_index);
/**
* Query info over types.
*/
@ -743,7 +728,7 @@ void CustomData_blend_write(BlendWriter *writer,
void CustomData_blend_read(struct BlendDataReader *reader, struct CustomData *data, int count);
size_t CustomData_get_elem_size(struct CustomDataLayer *layer);
size_t CustomData_get_elem_size(const struct CustomDataLayer *layer);
#ifndef NDEBUG
struct DynStr;

View File

@ -36,10 +36,10 @@ struct PropertyRNA;
/* Data Management */
/**
* Remove the given NLA strip from the NLA track it occupies, free the strip's data,
* and the strip itself.
* Frees the given NLA strip, and calls #BKE_nlastrip_remove_and_free to
* remove and free all children strips.
*/
void BKE_nlastrip_free(ListBase *strips, struct NlaStrip *strip, bool do_id_user);
void BKE_nlastrip_free(struct NlaStrip *strip, bool do_id_user);
/**
* Remove the given NLA track from the set of NLA tracks, free the track's data,
* and the track itself.
@ -94,10 +94,22 @@ void BKE_nla_tracks_copy_from_adt(struct Main *bmain,
struct NlaTrack *BKE_nlatrack_add(struct AnimData *adt,
struct NlaTrack *prev,
bool is_liboverride);
/**
* Create a NLA Strip referencing the given Action.
*/
struct NlaStrip *BKE_nlastrip_new(struct bAction *act);
/*
* Removes the given NLA strip from the list of strips provided.
*/
void BKE_nlastrip_remove(ListBase *strips, struct NlaStrip *strip);
/*
* Removes the given NLA strip from the list of strips provided, and frees it's memory.
*/
void BKE_nlastrip_remove_and_free(ListBase *strips, struct NlaStrip *strip, const bool do_id_user);
/**
* Add new NLA-strip to the top of the NLA stack - i.e.
* into the last track if space, or a new one otherwise.
@ -139,13 +151,9 @@ void BKE_nlastrips_sort_strips(ListBase *strips);
void BKE_nlastrips_add_strip_unsafe(ListBase *strips, struct NlaStrip *strip);
/**
* \brief NULL checks incoming strip and verifies no overlap / invalid
* configuration against other strips in NLA Track.
*
* \param strips:
* \param strip:
* \return true
* \return false
* NULL checks incoming strip and verifies no overlap / invalid
* configuration against other strips in NLA Track before calling
* #BKE_nlastrips_add_strip_unsafe.
*/
bool BKE_nlastrips_add_strip(ListBase *strips, struct NlaStrip *strip);
@ -215,11 +223,16 @@ bool BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end);
void BKE_nlatrack_sort_strips(struct NlaTrack *nlt);
/**
* Add the given NLA-Strip to the given NLA-Track, assuming that it
* isn't currently attached to another one.
* Add the given NLA-Strip to the given NLA-Track.
* Calls #BKE_nlastrips_add_strip to check if strip can be added.
*/
bool BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip, bool is_liboverride);
/**
* Remove the NLA-Strip from the given NLA-Track.
*/
void BKE_nlatrack_remove_strip(struct NlaTrack *track, struct NlaStrip *strip);
/**
* Get the extents of the given NLA-Track including gaps between strips,
* returning whether this succeeded or not

View File

@ -249,8 +249,8 @@ set(SRC
intern/particle_distribute.c
intern/particle_system.c
intern/pbvh.cc
intern/pbvh_colors.cc
intern/pbvh_bmesh.cc
intern/pbvh_colors.cc
intern/pbvh_pixels.cc
intern/pbvh_uv_islands.cc
intern/pointcache.c

View File

@ -3654,7 +3654,7 @@ void CustomData_bmesh_free_block_data(CustomData *data, void *block)
}
}
static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
void CustomData_bmesh_alloc_block(CustomData *data, void **block)
{
if (*block) {
CustomData_bmesh_free_block(data, block);
@ -3689,19 +3689,23 @@ void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data,
}
}
static void CustomData_bmesh_set_default_n(CustomData *data, void **block, const int n)
void CustomData_data_set_default_value(const int type, void *elem)
{
int offset = data->layers[n].offset;
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if (typeInfo->set_default_value) {
typeInfo->set_default_value(POINTER_OFFSET(*block, offset), 1);
typeInfo->set_default_value(elem, 1);
}
else {
memset(POINTER_OFFSET(*block, offset), 0, typeInfo->size);
memset(elem, 0, typeInfo->size);
}
}
static void CustomData_bmesh_set_default_n(CustomData *data, void **block, const int n)
{
const int offset = data->layers[n].offset;
CustomData_data_set_default_value(data->layers[n].type, POINTER_OFFSET(*block, offset));
}
void CustomData_bmesh_set_default(CustomData *data, void **block)
{
if (*block == nullptr) {
@ -3891,8 +3895,8 @@ void CustomData_data_copy_value(int type, const void *source, void *dest)
return;
}
if (typeInfo->copyvalue) {
typeInfo->copyvalue(source, dest, CDT_MIX_NOMIX, 0.0f);
if (typeInfo->copy) {
typeInfo->copy(source, dest, 1);
}
else {
memcpy(dest, source, typeInfo->size);
@ -4067,115 +4071,6 @@ void CustomData_bmesh_interp(CustomData *data,
}
}
void CustomData_to_bmesh_block(const CustomData *source,
CustomData *dest,
int src_index,
void **dest_block,
bool use_default_init)
{
if (*dest_block == nullptr) {
CustomData_bmesh_alloc_block(dest, dest_block);
}
/* copies a layer at a time */
int dest_i = 0;
for (int src_i = 0; src_i < source->totlayer; src_i++) {
/* find the first dest layer with type >= the source type
* (this should work because layers are ordered by type)
*/
while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
if (use_default_init) {
CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
}
dest_i++;
}
/* if there are no more dest layers, we're done */
if (dest_i >= dest->totlayer) {
break;
}
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
int offset = dest->layers[dest_i].offset;
const void *src_data = source->layers[src_i].data;
void *dest_data = POINTER_OFFSET(*dest_block, offset);
const LayerTypeInfo *typeInfo = layerType_getInfo(dest->layers[dest_i].type);
const size_t src_offset = size_t(src_index) * typeInfo->size;
if (typeInfo->copy) {
typeInfo->copy(POINTER_OFFSET(src_data, src_offset), dest_data, 1);
}
else {
memcpy(dest_data, POINTER_OFFSET(src_data, src_offset), typeInfo->size);
}
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
* increment dest_i
*/
dest_i++;
}
}
if (use_default_init) {
while (dest_i < dest->totlayer) {
CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
dest_i++;
}
}
}
void CustomData_from_bmesh_block(const CustomData *source,
CustomData *dest,
void *src_block,
int dest_index)
{
/* copies a layer at a time */
int dest_i = 0;
for (int src_i = 0; src_i < source->totlayer; src_i++) {
if (source->layers[src_i].flag & CD_FLAG_NOCOPY) {
continue;
}
/* find the first dest layer with type >= the source type
* (this should work because layers are ordered by type)
*/
while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
dest_i++;
}
/* if there are no more dest layers, we're done */
if (dest_i >= dest->totlayer) {
return;
}
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
const LayerTypeInfo *typeInfo = layerType_getInfo(dest->layers[dest_i].type);
int offset = source->layers[src_i].offset;
const void *src_data = POINTER_OFFSET(src_block, offset);
void *dst_data = POINTER_OFFSET(dest->layers[dest_i].data,
size_t(dest_index) * typeInfo->size);
if (typeInfo->copy) {
typeInfo->copy(src_data, dst_data, 1);
}
else {
memcpy(dst_data, src_data, typeInfo->size);
}
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
* increment dest_i
*/
dest_i++;
}
}
}
void CustomData_file_write_info(int type, const char **r_struct_name, int *r_struct_num)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@ -5308,7 +5203,7 @@ eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
} // namespace blender::bke
size_t CustomData_get_elem_size(CustomDataLayer *layer)
size_t CustomData_get_elem_size(const CustomDataLayer *layer)
{
return LAYERTYPEINFO[layer->type].size;
}

View File

@ -61,7 +61,7 @@ static void nla_tweakmode_find_active(const ListBase /* NlaTrack */ *nla_tracks,
/* Freeing ------------------------------------------- */
void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user)
void BKE_nlastrip_free(NlaStrip *strip, const bool do_id_user)
{
NlaStrip *cs, *csn;
@ -73,7 +73,7 @@ void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user)
/* free child-strips */
for (cs = strip->strips.first; cs; cs = csn) {
csn = cs->next;
BKE_nlastrip_free(&strip->strips, cs, do_id_user);
BKE_nlastrip_remove_and_free(&strip->strips, cs, do_id_user);
}
/* remove reference to action */
@ -81,10 +81,6 @@ void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user)
id_us_min(&strip->act->id);
}
/* free remapping info */
// if (strip->remap)
// BKE_animremap_free();
/* free own F-Curves */
BKE_fcurves_free(&strip->fcurves);
@ -92,12 +88,7 @@ void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user)
free_fmodifiers(&strip->modifiers);
/* free the strip itself */
if (strips) {
BLI_freelinkN(strips, strip);
}
else {
MEM_freeN(strip);
}
MEM_freeN(strip);
}
void BKE_nlatrack_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user)
@ -112,7 +103,7 @@ void BKE_nlatrack_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user)
/* free strips */
for (strip = nlt->strips.first; strip; strip = stripn) {
stripn = strip->next;
BKE_nlastrip_free(&nlt->strips, strip, do_id_user);
BKE_nlastrip_remove_and_free(&nlt->strips, strip, do_id_user);
}
/* free NLA track itself now */
@ -875,7 +866,7 @@ void BKE_nlastrips_clear_metastrip(ListBase *strips, NlaStrip *strip)
}
/* free the meta-strip now */
BKE_nlastrip_free(strips, strip, true);
BKE_nlastrip_remove_and_free(strips, strip, true);
}
void BKE_nlastrips_clear_metas(ListBase *strips, bool only_sel, bool only_temp)
@ -1190,6 +1181,12 @@ bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip, const bool is_libove
return BKE_nlastrips_add_strip(&nlt->strips, strip);
}
void BKE_nlatrack_remove_strip(NlaTrack *track, NlaStrip *strip)
{
BLI_assert(track);
BKE_nlastrip_remove(&track->strips, strip);
}
bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2])
{
NlaStrip *strip;
@ -1318,6 +1315,18 @@ NlaStrip *BKE_nlastrip_find_active(NlaTrack *nlt)
return nlastrip_find_active(&nlt->strips);
}
void BKE_nlastrip_remove(ListBase *strips, NlaStrip *strip)
{
BLI_assert(strips);
BLI_remlink(strips, strip);
}
void BKE_nlastrip_remove_and_free(ListBase *strips, NlaStrip *strip, const bool do_id_user)
{
BKE_nlastrip_remove(strips, strip);
BKE_nlastrip_free(strip, do_id_user);
}
void BKE_nlastrip_set_active(AnimData *adt, NlaStrip *strip)
{
NlaTrack *nlt;

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2023 Blender Foundation. All rights reserved. */
#include "BLI_listbase.h"
#include "BKE_nla.h"
#include "DNA_anim_types.h"
@ -20,19 +22,19 @@ TEST(nla_strip, BKE_nlastrip_recalculate_blend)
strip.start = 1;
strip.end = 10;
/* Scaling a strip up doesn't affect the blend in/out value */
/* Scaling a strip up doesn't affect the blend in/out value. */
strip.end = 20;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 4.0);
EXPECT_FLOAT_EQ(strip.blendout, 5.0);
/* Scaling a strip down affects the blend-in value before the blend-out value */
/* Scaling a strip down affects the blend-in value before the blend-out value. */
strip.end = 7;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 1.0);
EXPECT_FLOAT_EQ(strip.blendout, 5.0);
/* Scaling a strip down to nothing updates the blend in/out values accordingly */
/* Scaling a strip down to nothing updates the blend in/out values accordingly. */
strip.end = 1.1;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 0.0);
@ -63,4 +65,30 @@ TEST(nla_strip, BKE_nlastrips_add_strip)
EXPECT_TRUE(BKE_nlastrips_add_strip(&strips, &strip2));
}
TEST(nla_track, BKE_nlatrack_remove_strip)
{
NlaTrack track{};
ListBase strips{};
NlaStrip strip1{};
strip1.start = 0;
strip1.end = 10;
NlaStrip strip2{};
strip2.start = 11;
strip2.end = 20;
// Add NLA strips to the NLATrack.
BKE_nlastrips_add_strip(&strips, &strip1);
BKE_nlastrips_add_strip(&strips, &strip2);
track.strips = strips;
// ensure we have 2 strips in the track.
EXPECT_EQ(2, BLI_listbase_count(&track.strips));
BKE_nlatrack_remove_strip(&track, &strip2);
EXPECT_EQ(1, BLI_listbase_count(&track.strips));
// ensure the correct strip was removed.
EXPECT_EQ(-1, BLI_findindex(&track.strips, &strip2));
}
} // namespace blender::bke::tests

View File

@ -265,7 +265,7 @@ static DupliObject *make_dupli(const DupliContext *ctx,
/* Store geometry set data for attribute lookup in innermost to outermost
* order, copying only non-null entries to save space. */
const int max_instance = sizeof(dob->instance_data) / sizeof(void *);
const int max_instance = ARRAY_SIZE(dob->instance_data);
int next_instance = 0;
if (geometry != nullptr) {
dob->instance_idx[next_instance] = int(instance_index);
@ -1821,7 +1821,7 @@ static bool find_geonode_attribute_rgba(const DupliObject *dupli,
using namespace blender;
/* Loop over layers from innermost to outermost. */
for (const int i : IndexRange(sizeof(dupli->instance_data) / sizeof(void *))) {
for (const int i : IndexRange(ARRAY_SIZE(dupli->instance_data))) {
/* Skip non-geonode layers. */
if (dupli->instance_data[i] == nullptr) {
continue;

View File

@ -1704,7 +1704,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Object *ob, RigidBodyO
}
}
/* Make transformed objects temporarily kinmatic
/* Make transformed objects temporarily kinematic
* so that they can be moved by the user during simulation. */
if (is_selected && (G.moving & G_TRANSFORM_OBJ)) {
RB_body_set_kinematic_state(rbo->shared->physics_object, true);

View File

@ -352,7 +352,7 @@ struct StaticOrHeapIntStorage {
static void static_or_heap_storage_init(StaticOrHeapIntStorage *storage)
{
storage->static_storage_len = sizeof(storage->static_storage) / sizeof(*storage->static_storage);
storage->static_storage_len = ARRAY_SIZE(storage->static_storage);
storage->heap_storage = nullptr;
storage->heap_storage_len = 0;
}

View File

@ -538,13 +538,14 @@ void tracking_cameraIntrinscisOptionsFromTracking(
void tracking_trackingCameraFromIntrinscisOptions(
MovieTracking *tracking, const libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
{
float aspy = 1.0f / tracking->camera.pixel_aspect;
MovieTrackingCamera *camera = &tracking->camera;
camera->focal = camera_intrinsics_options->focal_length;
/* NOTE: The image size stored in the `camera_intrinsics_options` is aspect-ratio corrected,
* so there is no need to "un-apply" it from the principal point. */
const float principal_px[2] = {camera_intrinsics_options->principal_point_x,
camera_intrinsics_options->principal_point_y / (double)aspy};
camera_intrinsics_options->principal_point_y};
tracking_principal_point_pixel_to_normalized(principal_px,
camera_intrinsics_options->image_width,

View File

@ -806,6 +806,10 @@ extern bool BLI_memory_is_zero(const void *arr, size_t arr_size);
{ \
return a = (_enum_type)(uint64_t(a) & uint64_t(b)); \
} \
inline _enum_type &operator^=(_enum_type &a, _enum_type b) \
{ \
return a = (_enum_type)(uint64_t(a) ^ uint64_t(b)); \
} \
} /* extern "C++" */
#else

View File

@ -281,10 +281,10 @@ set(SRC
BLI_math_solvers.h
BLI_math_statistics.h
BLI_math_time.h
BLI_math_vector_mpq_types.hh
BLI_math_vector_types.hh
BLI_math_vector.h
BLI_math_vector.hh
BLI_math_vector_mpq_types.hh
BLI_math_vector_types.hh
BLI_memarena.h
BLI_memblock.h
BLI_memiter.h
@ -490,13 +490,13 @@ if(WITH_GTESTS)
tests/BLI_math_bits_test.cc
tests/BLI_math_color_test.cc
tests/BLI_math_geom_test.cc
tests/BLI_math_matrix_types_test.cc
tests/BLI_math_matrix_test.cc
tests/BLI_math_matrix_types_test.cc
tests/BLI_math_rotation_test.cc
tests/BLI_math_solvers_test.cc
tests/BLI_math_time_test.cc
tests/BLI_math_vector_types_test.cc
tests/BLI_math_vector_test.cc
tests/BLI_math_vector_types_test.cc
tests/BLI_memiter_test.cc
tests/BLI_memory_utils_test.cc
tests/BLI_mesh_boolean_test.cc

View File

@ -85,6 +85,7 @@
#include "BLI_span.hh"
#include "BLI_string_ref.hh"
#include "BLI_task.hh"
#include "BLI_vector.hh"
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
@ -110,6 +111,7 @@ using blender::IndexRange;
using blender::MutableSpan;
using blender::Span;
using blender::StringRef;
using blender::Vector;
static char bm_edge_flag_from_mflag(const short mflag)
{
@ -164,6 +166,63 @@ static BMFace *bm_face_create_from_mpoly(BMesh &bm,
return BM_face_create(&bm, verts.data(), edges.data(), loops.size(), nullptr, BM_CREATE_SKIP_CD);
}
struct MeshToBMeshLayerInfo {
eCustomDataType type;
/** The layer's position in the BMesh element's data block. */
int bmesh_offset;
/** The mesh's #CustomDataLayer::data. When null, the BMesh block is set to its default value. */
const void *mesh_data;
/** The size of every custom data element. */
size_t elem_size;
};
/**
* Calculate the necessary information to copy every data layer from the Mesh to the BMesh.
*/
static Vector<MeshToBMeshLayerInfo> mesh_to_bm_copy_info_calc(const CustomData &mesh_data,
CustomData &bm_data)
{
Vector<MeshToBMeshLayerInfo> infos;
std::array<int, CD_NUMTYPES> per_type_index;
per_type_index.fill(0);
for (const int i : IndexRange(bm_data.totlayer)) {
const CustomDataLayer &bm_layer = bm_data.layers[i];
const eCustomDataType type = eCustomDataType(bm_layer.type);
const int mesh_layer_index =
bm_layer.name[0] == '\0' ?
CustomData_get_layer_index_n(&mesh_data, type, per_type_index[type]) :
CustomData_get_named_layer_index(&mesh_data, type, bm_layer.name);
MeshToBMeshLayerInfo info{};
info.type = type;
info.bmesh_offset = bm_layer.offset;
info.mesh_data = (mesh_layer_index == -1) ? nullptr : mesh_data.layers[mesh_layer_index].data;
info.elem_size = CustomData_get_elem_size(&bm_layer);
infos.append(info);
per_type_index[type]++;
}
return infos;
}
static void mesh_attributes_copy_to_bmesh_block(CustomData &data,
const Span<MeshToBMeshLayerInfo> copy_info,
const int mesh_index,
BMHeader &header)
{
CustomData_bmesh_alloc_block(&data, &header.data);
for (const MeshToBMeshLayerInfo &info : copy_info) {
if (info.mesh_data) {
CustomData_data_copy_value(info.type,
POINTER_OFFSET(info.mesh_data, info.elem_size * mesh_index),
POINTER_OFFSET(header.data, info.bmesh_offset));
}
else {
CustomData_data_set_default_value(info.type, POINTER_OFFSET(header.data, info.bmesh_offset));
}
}
}
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
{
if (!me) {
@ -259,6 +318,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
CustomData_bmesh_merge(&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, bm, BM_LOOP);
}
const Vector<MeshToBMeshLayerInfo> vert_info = mesh_to_bm_copy_info_calc(mesh_vdata, bm->vdata);
const Vector<MeshToBMeshLayerInfo> edge_info = mesh_to_bm_copy_info_calc(mesh_edata, bm->edata);
const Vector<MeshToBMeshLayerInfo> poly_info = mesh_to_bm_copy_info_calc(mesh_pdata, bm->pdata);
const Vector<MeshToBMeshLayerInfo> loop_info = mesh_to_bm_copy_info_calc(mesh_ldata, bm->ldata);
/* -------------------------------------------------------------------- */
/* Shape Key */
int tot_shape_keys = 0;
@ -393,8 +457,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
copy_v3_v3(v->no, vert_normals[i]);
}
/* Copy Custom Data */
CustomData_to_bmesh_block(&mesh_vdata, &bm->vdata, i, &v->head.data, true);
mesh_attributes_copy_to_bmesh_block(bm->vdata, vert_info, i, v->head);
/* Set shape key original index. */
if (cd_shape_keyindex_offset != -1) {
@ -432,8 +495,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
BM_elem_flag_enable(e, BM_ELEM_SMOOTH);
}
/* Copy Custom Data */
CustomData_to_bmesh_block(&mesh_edata, &bm->edata, i, &e->head.data, true);
mesh_attributes_copy_to_bmesh_block(bm->edata, edge_info, i, e->head);
}
if (is_new) {
bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */
@ -491,12 +553,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
/* Don't use 'j' since we may have skipped some faces, hence some loops. */
BM_elem_index_set(l_iter, totloops++); /* set_ok */
/* Save index of corresponding #MLoop. */
CustomData_to_bmesh_block(&mesh_ldata, &bm->ldata, j++, &l_iter->head.data, true);
mesh_attributes_copy_to_bmesh_block(bm->ldata, loop_info, j, l_iter->head);
j++;
} while ((l_iter = l_iter->next) != l_first);
/* Copy Custom Data */
CustomData_to_bmesh_block(&mesh_pdata, &bm->pdata, i, &f->head.data, true);
mesh_attributes_copy_to_bmesh_block(bm->pdata, poly_info, i, f->head);
if (params->calc_face_normal) {
BM_face_normal_update(f);
@ -998,6 +1059,66 @@ static void convert_bmesh_selection_flags_to_mesh_attributes(BMesh &bm,
}
}
struct BMeshToMeshLayerInfo {
eCustomDataType type;
/** The layer's position in the BMesh element's data block. */
int bmesh_offset;
/** The mesh's #CustomDataLayer::data. When null, the BMesh block is set to its default value. */
void *mesh_data;
/** The size of every custom data element. */
size_t elem_size;
};
/**
* Calculate the necessary information to copy every data layer from the BMesh to the Mesh.
*/
static Vector<BMeshToMeshLayerInfo> bm_to_mesh_copy_info_calc(const CustomData &bm_data,
CustomData &mesh_data)
{
Vector<BMeshToMeshLayerInfo> infos;
std::array<int, CD_NUMTYPES> per_type_index;
per_type_index.fill(0);
for (const int i : IndexRange(mesh_data.totlayer)) {
const CustomDataLayer &mesh_layer = mesh_data.layers[i];
const eCustomDataType type = eCustomDataType(mesh_layer.type);
const int bm_layer_index =
mesh_layer.name[0] == '\0' ?
CustomData_get_layer_index_n(&bm_data, type, per_type_index[type]) :
CustomData_get_named_layer_index(&bm_data, type, mesh_layer.name);
/* Skip layers that don't exist in `bm_data` or are explicitly set to not be
* copied. The layers are either set separately or shouldn't exist on the mesh. */
if (bm_layer_index == -1) {
continue;
}
const CustomDataLayer &bm_layer = bm_data.layers[bm_layer_index];
if (bm_layer.flag & CD_FLAG_NOCOPY) {
continue;
}
BMeshToMeshLayerInfo info{};
info.type = type;
info.bmesh_offset = bm_layer.offset;
info.mesh_data = mesh_layer.data;
info.elem_size = CustomData_get_elem_size(&mesh_layer);
infos.append(info);
per_type_index[type]++;
}
return infos;
}
static void bmesh_block_copy_to_mesh_attributes(const Span<BMeshToMeshLayerInfo> copy_info,
const int mesh_index,
const void *block)
{
for (const BMeshToMeshLayerInfo &info : copy_info) {
CustomData_data_copy_value(info.type,
POINTER_OFFSET(block, info.bmesh_offset),
POINTER_OFFSET(info.mesh_data, info.elem_size * mesh_index));
}
}
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
{
using namespace blender;
@ -1011,6 +1132,8 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
const int ototvert = me->totvert;
blender::Vector<int> ldata_layers_marked_nocopy;
/* Free custom data. */
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
@ -1041,9 +1164,17 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
&bm->ldata, CD_PROP_BOOL, BKE_uv_map_edge_select_name_get(layer_name, sub_layer_name));
int pin_layer_index = CustomData_get_named_layer_index(
&bm->ldata, CD_PROP_BOOL, BKE_uv_map_pin_name_get(layer_name, sub_layer_name));
int vertsel_offset = bm->ldata.layers[vertsel_layer_index].offset;
int edgesel_offset = bm->ldata.layers[edgesel_layer_index].offset;
int pin_offset = bm->ldata.layers[pin_layer_index].offset;
/* If ever the uv map associated bool layers become optional in BMesh as well (like in Mesh)
* this assert needs to be removed. For now it is a bug if they don't exist. */
BLI_assert(vertsel_layer_index >= 0 && edgesel_layer_index >= 0 && pin_layer_index >= 0);
int vertsel_offset = vertsel_layer_index >= 0 ? bm->ldata.layers[vertsel_layer_index].offset :
-1;
int edgesel_offset = edgesel_layer_index >= 0 ? bm->ldata.layers[edgesel_layer_index].offset :
-1;
int pin_offset = pin_layer_index >= 0 ? bm->ldata.layers[pin_layer_index].offset : -1;
bool need_vertsel = false;
bool need_edgesel = false;
bool need_pin = false;
@ -1051,10 +1182,20 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
BMIter liter;
BMLoop *l;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
need_vertsel |= BM_ELEM_CD_GET_BOOL(l, vertsel_offset);
need_edgesel |= BM_ELEM_CD_GET_BOOL(l, edgesel_offset);
need_pin |= BM_ELEM_CD_GET_BOOL(l, pin_offset);
if (vertsel_layer_index >= 0) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
need_vertsel |= BM_ELEM_CD_GET_BOOL(l, vertsel_offset);
}
}
if (edgesel_layer_index >= 0) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
need_edgesel |= BM_ELEM_CD_GET_BOOL(l, edgesel_offset);
}
}
if (pin_layer_index) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
need_pin |= BM_ELEM_CD_GET_BOOL(l, pin_offset);
}
}
}
@ -1063,18 +1204,21 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
}
else {
bm->ldata.layers[vertsel_layer_index].flag |= CD_FLAG_NOCOPY;
ldata_layers_marked_nocopy.append(vertsel_layer_index);
}
if (need_edgesel) {
bm->ldata.layers[edgesel_layer_index].flag &= ~CD_FLAG_NOCOPY;
}
else {
bm->ldata.layers[edgesel_layer_index].flag |= CD_FLAG_NOCOPY;
ldata_layers_marked_nocopy.append(edgesel_layer_index);
}
if (need_pin) {
bm->ldata.layers[pin_layer_index].flag &= ~CD_FLAG_NOCOPY;
}
else {
bm->ldata.layers[pin_layer_index].flag |= CD_FLAG_NOCOPY;
ldata_layers_marked_nocopy.append(pin_layer_index);
}
}
@ -1087,6 +1231,16 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly);
}
const Vector<BMeshToMeshLayerInfo> vert_info = bm_to_mesh_copy_info_calc(bm->vdata, me->vdata);
const Vector<BMeshToMeshLayerInfo> edge_info = bm_to_mesh_copy_info_calc(bm->edata, me->edata);
const Vector<BMeshToMeshLayerInfo> poly_info = bm_to_mesh_copy_info_calc(bm->pdata, me->pdata);
const Vector<BMeshToMeshLayerInfo> loop_info = bm_to_mesh_copy_info_calc(bm->ldata, me->ldata);
/* Clear the CD_FLAG_NOCOPY flags for the layers they were temporarily set on */
for (const int i : ldata_layers_marked_nocopy) {
bm->ldata.layers[i].flag &= ~CD_FLAG_NOCOPY;
}
CustomData_add_layer_named(
&me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, me->totvert, "position");
CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge);
@ -1119,8 +1273,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BM_elem_index_set(v, i); /* set_inline */
/* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
bmesh_block_copy_to_mesh_attributes(vert_info, i, v->head.data);
i++;
@ -1146,8 +1299,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BM_elem_index_set(e, i); /* set_inline */
/* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->edata, &me->edata, e->head.data, i);
bmesh_block_copy_to_mesh_attributes(edge_info, i, e->head.data);
i++;
BM_CHECK_ELEMENT(e);
@ -1176,8 +1328,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
mloop[j].e = BM_elem_index_get(l_iter->e);
mloop[j].v = BM_elem_index_get(l_iter->v);
/* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j);
bmesh_block_copy_to_mesh_attributes(loop_info, j, l_iter->head.data);
j++;
BM_CHECK_ELEMENT(l_iter);
@ -1189,8 +1340,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
me->act_face = i;
}
/* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->pdata, &me->pdata, f->head.data, i);
bmesh_block_copy_to_mesh_attributes(poly_info, i, f->head.data);
i++;
BM_CHECK_ELEMENT(f);
@ -1399,12 +1549,13 @@ static void bm_to_mesh_verts(const BMesh &bm,
MutableSpan<bool> select_vert,
MutableSpan<bool> hide_vert)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.vdata, mesh.vdata);
MutableSpan<float3> dst_vert_positions = mesh.vert_positions_for_write();
threading::parallel_for(dst_vert_positions.index_range(), 1024, [&](const IndexRange range) {
for (const int vert_i : range) {
const BMVert &src_vert = *bm_verts[vert_i];
copy_v3_v3(dst_vert_positions[vert_i], src_vert.co);
CustomData_from_bmesh_block(&bm.vdata, &mesh.vdata, src_vert.head.data, vert_i);
bmesh_block_copy_to_mesh_attributes(info, vert_i, src_vert.head.data);
}
if (!select_vert.is_empty()) {
for (const int vert_i : range) {
@ -1426,6 +1577,7 @@ static void bm_to_mesh_edges(const BMesh &bm,
MutableSpan<bool> hide_edge,
MutableSpan<bool> sharp_edge)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.edata, mesh.edata);
MutableSpan<MEdge> dst_edges = mesh.edges_for_write();
threading::parallel_for(dst_edges.index_range(), 512, [&](const IndexRange range) {
for (const int edge_i : range) {
@ -1434,7 +1586,7 @@ static void bm_to_mesh_edges(const BMesh &bm,
dst_edge.v1 = BM_elem_index_get(src_edge.v1);
dst_edge.v2 = BM_elem_index_get(src_edge.v2);
dst_edge.flag = bm_edge_flag_to_mflag(&src_edge);
CustomData_from_bmesh_block(&bm.edata, &mesh.edata, src_edge.head.data, edge_i);
bmesh_block_copy_to_mesh_attributes(info, edge_i, src_edge.head.data);
}
if (!select_edge.is_empty()) {
for (const int edge_i : range) {
@ -1461,6 +1613,7 @@ static void bm_to_mesh_faces(const BMesh &bm,
MutableSpan<bool> hide_poly,
MutableSpan<int> material_indices)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.pdata, mesh.pdata);
MutableSpan<MPoly> dst_polys = mesh.polys_for_write();
threading::parallel_for(dst_polys.index_range(), 1024, [&](const IndexRange range) {
for (const int face_i : range) {
@ -1469,7 +1622,7 @@ static void bm_to_mesh_faces(const BMesh &bm,
dst_poly.totloop = src_face.len;
dst_poly.loopstart = BM_elem_index_get(BM_FACE_FIRST_LOOP(&src_face));
dst_poly.flag = bm_face_flag_to_mflag(&src_face);
CustomData_from_bmesh_block(&bm.pdata, &mesh.pdata, src_face.head.data, face_i);
bmesh_block_copy_to_mesh_attributes(info, face_i, src_face.head.data);
}
if (!select_poly.is_empty()) {
for (const int face_i : range) {
@ -1491,6 +1644,7 @@ static void bm_to_mesh_faces(const BMesh &bm,
static void bm_to_mesh_loops(const BMesh &bm, const Span<const BMLoop *> bm_loops, Mesh &mesh)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.ldata, mesh.ldata);
MutableSpan<MLoop> dst_loops = mesh.loops_for_write();
threading::parallel_for(dst_loops.index_range(), 1024, [&](const IndexRange range) {
for (const int loop_i : range) {
@ -1498,7 +1652,7 @@ static void bm_to_mesh_loops(const BMesh &bm, const Span<const BMLoop *> bm_loop
MLoop &dst_loop = dst_loops[loop_i];
dst_loop.v = BM_elem_index_get(src_loop.v);
dst_loop.e = BM_elem_index_get(src_loop.e);
CustomData_from_bmesh_block(&bm.ldata, &mesh.ldata, src_loop.head.data, loop_i);
bmesh_block_copy_to_mesh_attributes(info, loop_i, src_loop.head.data);
}
});
}

View File

@ -1197,8 +1197,8 @@ static void bmw_FaceLoopWalker_begin(BMWalker *walker, void *data)
{
BMwFaceLoopWalker *lwalk, owalk, *owalk_pt;
BMEdge *e = data;
/* BMesh *bm = walker->bm; */ /* UNUSED */
/* int fcount = BM_edge_face_count(e); */ /* UNUSED */
// BMesh *bm = walker->bm; /* UNUSED */
// int fcount = BM_edge_face_count(e); /* UNUSED */
if (!bmw_FaceLoopWalker_edge_begins_loop(walker, e)) {
return;

View File

@ -1183,7 +1183,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
f = BM_face_create_verts(bm, varr, j, es->l->f, BM_CREATE_NOP, true);
BMO_face_flag_enable(bm, f, ELE_NEW);
/* Copy for loop data, otherwise UVs and vcols are no good.
/* Copy for loop data, otherwise UVs and vertex-colors are no good.
* tiny speedup here we could be more clever and copy from known adjacent data
* also - we could attempt to interpolate the loop data,
* this would be much slower but more useful too. */

View File

@ -225,7 +225,7 @@ set(SRC
DRW_select_buffer.h
intern/DRW_gpu_wrapper.hh
intern/DRW_render.h
intern/draw_attributes.h
intern/draw_attributes.hh
intern/draw_cache.h
intern/draw_cache_extract.hh
intern/draw_cache_impl.h
@ -234,7 +234,7 @@ set(SRC
intern/draw_command.hh
intern/draw_common.h
intern/draw_common_shader_shared.h
intern/draw_curves_private.h
intern/draw_curves_private.hh
intern/draw_debug.h
intern/draw_debug.hh
intern/draw_hair_private.h

View File

@ -21,8 +21,7 @@ void main()
float light_count = 0.0;
uint light_cull = 0u;
vec2 px = gl_FragCoord.xy;
LIGHT_FOREACH_BEGIN_LOCAL(light_cull_buf, light_zbin_buf, light_tile_buf, px, vP_z, l_idx)
{
LIGHT_FOREACH_BEGIN_LOCAL (light_cull_buf, light_zbin_buf, light_tile_buf, px, vP_z, l_idx) {
LightData light = light_buf[l_idx];
light_cull |= 1u << l_idx;
light_count += 1.0;

View File

@ -192,4 +192,4 @@ void main()
break;
}
}
}
}

View File

@ -38,4 +38,4 @@ void main()
}
tile_start += lod_len;
}
}
}

View File

@ -126,4 +126,4 @@ void main()
clear_dispatch_buf.num_groups_x = pages_infos_buf.page_size / SHADOW_PAGE_CLEAR_GROUP_SIZE;
clear_dispatch_buf.num_groups_y = pages_infos_buf.page_size / SHADOW_PAGE_CLEAR_GROUP_SIZE;
clear_dispatch_buf.num_groups_z = 0;
}
}

View File

@ -51,4 +51,4 @@ void main()
}
tile_start += lod_len;
}
}
}

View File

@ -52,4 +52,4 @@ void main()
}
}
}
}
}

View File

@ -91,4 +91,4 @@ void main()
}
}
}
}
}

View File

@ -29,4 +29,4 @@ void main()
vec2 pixel = vec2(gl_GlobalInvocationID.xy);
shadow_tag_usage(vP, P, pixel);
}
}

View File

@ -12,4 +12,4 @@
void main()
{
shadow_tag_usage(interp.vP, interp.P, gl_FragCoord.xy);
}
}

View File

@ -101,4 +101,4 @@ void shadow_tag_usage(vec3 vP, vec3 P, vec2 pixel)
shadow_tag_usage_tilemap(l_idx, P, dist_to_cam, false);
}
LIGHT_FOREACH_END
}
}

View File

@ -19,4 +19,4 @@ void main()
interp.vP = point_world_to_view(interp.P);
gl_Position = point_world_to_ndc(interp.P);
}
}

View File

@ -395,4 +395,4 @@ void main()
EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP0, vec2(0.0), 2), 0.0, 1e-4);
}
}
}
}

View File

@ -74,4 +74,4 @@ void main()
* thread 0. */
}
LIGHT_FOREACH_END
}
}

View File

@ -178,4 +178,4 @@ void main()
/* Clamp it as it can underflow if there is too much tile present on screen. */
pages_infos_buf.page_free_count = max(pages_infos_buf.page_free_count, 0);
}
}
}

View File

@ -90,4 +90,4 @@ void main()
tiles_buf[tile_store] = tile;
}
}
}
}

View File

@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "eevee_defines.hh"

View File

@ -5,10 +5,14 @@
* \ingroup draw_engine
*/
#include "BKE_curves.h"
#include "DRW_render.h"
#include "ED_view3d.h"
#include "DEG_depsgraph_query.h"
#include "draw_cache_impl.h"
#include "overlay_private.hh"
@ -17,7 +21,10 @@ void OVERLAY_edit_curves_init(OVERLAY_Data *vedata)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Object *obact_orig = DEG_get_original_object(draw_ctx->obact);
const Curves &curves_id = *static_cast<const Curves *>(obact_orig->data);
pd->edit_curves.do_points = curves_id.selection_domain == ATTR_DOMAIN_POINT;
pd->edit_curves.do_zbufclip = XRAY_FLAG_ENABLED(draw_ctx->v3d);
/* Create view with depth offset. */
@ -39,10 +46,12 @@ void OVERLAY_edit_curves_cache_init(OVERLAY_Data *vedata)
/* Run Twice for in-front passes. */
for (int i = 0; i < 2; i++) {
DRW_PASS_CREATE(psl->edit_curves_points_ps[i], (state | pd->clipping_state));
sh = OVERLAY_shader_edit_particle_point();
grp = pd->edit_curves_points_grp[i] = DRW_shgroup_create(sh, psl->edit_curves_points_ps[i]);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
if (pd->edit_curves.do_points) {
DRW_PASS_CREATE(psl->edit_curves_points_ps[i], (state | pd->clipping_state));
sh = OVERLAY_shader_edit_particle_point();
grp = pd->edit_curves_points_grp[i] = DRW_shgroup_create(sh, psl->edit_curves_points_ps[i]);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
}
DRW_PASS_CREATE(psl->edit_curves_lines_ps[i], (state | pd->clipping_state));
sh = OVERLAY_shader_edit_particle_strand();
@ -56,9 +65,11 @@ static void overlay_edit_curves_add_ob_to_pass(OVERLAY_PrivateData *pd, Object *
{
Curves *curves = static_cast<Curves *>(ob->data);
DRWShadingGroup *point_shgrp = pd->edit_curves_points_grp[in_front];
struct GPUBatch *geom_points = DRW_curves_batch_cache_get_edit_points(curves);
DRW_shgroup_call_no_cull(point_shgrp, geom_points, ob);
if (pd->edit_curves.do_points) {
DRWShadingGroup *point_shgrp = pd->edit_curves_points_grp[in_front];
struct GPUBatch *geom_points = DRW_curves_batch_cache_get_edit_points(curves);
DRW_shgroup_call_no_cull(point_shgrp, geom_points, ob);
}
DRWShadingGroup *lines_shgrp = pd->edit_curves_lines_grp[in_front];
struct GPUBatch *geom_lines = DRW_curves_batch_cache_get_edit_lines(curves);
@ -89,12 +100,16 @@ void OVERLAY_edit_curves_draw(OVERLAY_Data *vedata)
if (pd->edit_curves.do_zbufclip) {
DRW_view_set_active(pd->view_edit_curves);
DRW_draw_pass(psl->edit_curves_points_ps[NOT_IN_FRONT]);
if (pd->edit_curves.do_points) {
DRW_draw_pass(psl->edit_curves_points_ps[NOT_IN_FRONT]);
}
DRW_draw_pass(psl->edit_curves_lines_ps[NOT_IN_FRONT]);
}
else {
DRW_view_set_active(pd->view_edit_curves);
DRW_draw_pass(psl->edit_curves_points_ps[IN_FRONT]);
if (pd->edit_curves.do_points) {
DRW_draw_pass(psl->edit_curves_points_ps[IN_FRONT]);
}
DRW_draw_pass(psl->edit_curves_lines_ps[IN_FRONT]);
}
}

View File

@ -362,6 +362,7 @@ typedef struct OVERLAY_PrivateData {
int flag; /** Copy of #v3d->overlay.edit_flag. */
} edit_mesh;
struct {
bool do_points;
bool do_zbufclip;
} edit_curves;
struct {

View File

@ -59,6 +59,6 @@ struct ExtrudedFrustum {
struct ShadowPassData {
float4 far_plane;
float3 light_direction_ws;
packed_float3 light_direction_ws;
int _padding;
};

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2022 Blender Foundation. All rights reserved. */
#include "draw_attributes.h"
#include "draw_attributes.hh"
/* Return true if the given DRW_AttributeRequest is already in the requests. */
static bool drw_attributes_has_request(const DRW_Attributes *requests, DRW_AttributeRequest req)

View File

@ -9,9 +9,7 @@
#pragma once
#ifdef __cplusplus
# include <mutex>
#endif
#include <mutex>
#include "DNA_customdata_types.h"
@ -24,23 +22,19 @@
#include "GPU_shader.h"
#include "GPU_vertex_format.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct DRW_AttributeRequest {
struct DRW_AttributeRequest {
eCustomDataType cd_type;
int layer_index;
eAttrDomain domain;
char attribute_name[64];
} DRW_AttributeRequest;
};
typedef struct DRW_Attributes {
struct DRW_Attributes {
DRW_AttributeRequest requests[GPU_MAX_ATTR];
int num_requests;
} DRW_Attributes;
};
typedef struct DRW_MeshCDMask {
struct DRW_MeshCDMask {
uint32_t uv : 8;
uint32_t tan : 8;
uint32_t orco : 1;
@ -50,7 +44,7 @@ typedef struct DRW_MeshCDMask {
* Edit uv layer is from the base edit mesh as modifiers could remove it. (see #68857)
*/
uint32_t edit_uv : 1;
} DRW_MeshCDMask;
};
/* Keep `DRW_MeshCDMask` struct within a `uint32_t`.
* bit-wise and atomic operations are used to compare and update the struct.
@ -59,11 +53,9 @@ BLI_STATIC_ASSERT(sizeof(DRW_MeshCDMask) <= sizeof(uint32_t), "DRW_MeshCDMask ex
void drw_attributes_clear(DRW_Attributes *attributes);
#ifdef __cplusplus
void drw_attributes_merge(DRW_Attributes *dst,
const DRW_Attributes *src,
std::mutex &render_mutex);
#endif
/* Return true if all requests in b are in a. */
bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b);
@ -78,7 +70,3 @@ bool drw_custom_data_match_attribute(const CustomData *custom_data,
const char *name,
int *r_layer_index,
eCustomDataType *r_type);
#ifdef __cplusplus
}
#endif

View File

@ -22,7 +22,7 @@
#include "GPU_index_buffer.h"
#include "GPU_vertex_buffer.h"
#include "draw_attributes.h"
#include "draw_attributes.hh"
struct DRWSubdivCache;
struct MeshRenderData;

View File

@ -34,10 +34,10 @@
#include "DRW_render.h"
#include "draw_attributes.h"
#include "draw_attributes.hh"
#include "draw_cache_impl.h" /* own include */
#include "draw_cache_inline.h"
#include "draw_curves_private.h" /* own include */
#include "draw_curves_private.hh" /* own include */
#include "draw_shader.h"
using blender::ColorGeometry4f;

View File

@ -25,7 +25,7 @@
#include "GPU_batch.h"
#include "GPU_material.h"
#include "draw_attributes.h"
#include "draw_attributes.hh"
#include "draw_cache_impl.h"
#include "draw_cache_inline.h"
#include "draw_pointcloud_private.hh" /* own include */

View File

@ -26,7 +26,7 @@
#include "DRW_render.h"
#include "draw_cache_impl.h"
#include "draw_curves_private.h"
#include "draw_curves_private.hh"
#include "draw_hair_private.h"
#include "draw_manager.h"
#include "draw_shader.h"

View File

@ -10,26 +10,23 @@
#include "BKE_attribute.h"
#include "GPU_shader.h"
#include "draw_attributes.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "draw_attributes.hh"
struct Curves;
struct GPUVertBuf;
struct GPUBatch;
struct GPUMaterial;
#define MAX_THICKRES 2 /* see eHairType */
#define MAX_HAIR_SUBDIV 4 /* see hair_subdiv rna */
typedef enum CurvesEvalShader {
enum CurvesEvalShader {
CURVES_EVAL_CATMULL_ROM = 0,
CURVES_EVAL_BEZIER = 1,
} CurvesEvalShader;
};
#define CURVES_EVAL_SHADER_NUM 3
typedef struct CurvesEvalFinalCache {
struct CurvesEvalFinalCache {
/* Output of the subdivision stage: vertex buffer sized to subdiv level. */
GPUVertBuf *proc_buf;
@ -58,10 +55,10 @@ typedef struct CurvesEvalFinalCache {
/* Output of the subdivision stage: vertex buffers sized to subdiv level. This is only attributes
* on point domain. */
GPUVertBuf *attributes_buf[GPU_MAX_ATTR];
} CurvesEvalFinalCache;
};
/* Curves procedural display: Evaluation is done on the GPU. */
typedef struct CurvesEvalCache {
struct CurvesEvalCache {
/* Control point positions on evaluated data-block combined with parameter data. */
GPUVertBuf *proc_point_buf;
@ -82,19 +79,15 @@ typedef struct CurvesEvalCache {
int strands_len;
int elems_len;
int point_len;
} CurvesEvalCache;
};
/**
* Ensure all necessary textures and buffers exist for GPU accelerated drawing.
*/
bool curves_ensure_procedural_data(struct Curves *curves,
struct CurvesEvalCache **r_hair_cache,
struct GPUMaterial *gpu_material,
bool curves_ensure_procedural_data(Curves *curves,
CurvesEvalCache **r_hair_cache,
GPUMaterial *gpu_material,
int subdiv,
int thickness_res);
void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32]);
#ifdef __cplusplus
}
#endif

View File

@ -7,7 +7,7 @@
#include "DRW_pbvh.hh"
#include "draw_attributes.h"
#include "draw_attributes.hh"
#include "draw_manager.h"
#include "draw_pbvh.h"
@ -698,7 +698,7 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob)
drw_call_calc_orco(ob, ob_infos->orcotexfac);
/* Random float value. */
uint random = (DST.dupli_source) ?
DST.dupli_source->random_id :
DST.dupli_source->random_id :
/* TODO(fclem): this is rather costly to do at runtime. Maybe we can
* put it in ob->runtime and make depsgraph ensure it is up to date. */
BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0);

View File

@ -21,7 +21,7 @@
#include "DRW_gpu_wrapper.hh"
#include "DRW_render.h"
#include "draw_attributes.h"
#include "draw_attributes.hh"
#include "draw_cache_impl.h"
#include "draw_common.h"
#include "draw_manager.h"

View File

@ -7,36 +7,38 @@
#pragma once
#include "draw_curves_private.h"
#include "draw_hair_private.h"
#ifdef __cplusplus
# include "draw_curves_private.hh"
# include "draw_hair_private.h"
struct GPUShader;
enum eParticleRefineShaderType {
PART_REFINE_SHADER_TRANSFORM_FEEDBACK,
PART_REFINE_SHADER_TRANSFORM_FEEDBACK_WORKAROUND,
PART_REFINE_SHADER_COMPUTE,
};
/* draw_shader.cc */
GPUShader *DRW_shader_hair_refine_get(ParticleRefineShader refinement,
eParticleRefineShaderType sh_type);
GPUShader *DRW_shader_curves_refine_get(CurvesEvalShader type, eParticleRefineShaderType sh_type);
GPUShader *DRW_shader_debug_print_display_get();
GPUShader *DRW_shader_debug_draw_display_get();
GPUShader *DRW_shader_draw_visibility_compute_get();
GPUShader *DRW_shader_draw_view_finalize_get();
GPUShader *DRW_shader_draw_resource_finalize_get();
GPUShader *DRW_shader_draw_command_generate_get();
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct GPUShader;
typedef enum eParticleRefineShaderType {
PART_REFINE_SHADER_TRANSFORM_FEEDBACK,
PART_REFINE_SHADER_TRANSFORM_FEEDBACK_WORKAROUND,
PART_REFINE_SHADER_COMPUTE,
} eParticleRefineShaderType;
/* draw_shader.cc */
struct GPUShader *DRW_shader_hair_refine_get(ParticleRefineShader refinement,
eParticleRefineShaderType sh_type);
struct GPUShader *DRW_shader_curves_refine_get(CurvesEvalShader type,
eParticleRefineShaderType sh_type);
struct GPUShader *DRW_shader_debug_print_display_get(void);
struct GPUShader *DRW_shader_debug_draw_display_get(void);
struct GPUShader *DRW_shader_draw_visibility_compute_get(void);
struct GPUShader *DRW_shader_draw_view_finalize_get(void);
struct GPUShader *DRW_shader_draw_resource_finalize_get(void);
struct GPUShader *DRW_shader_draw_command_generate_get(void);
void DRW_shaders_free(void);
#ifdef __cplusplus

View File

@ -17,7 +17,7 @@
#include "BKE_attribute.hh"
#include "BKE_mesh.h"
#include "draw_attributes.h"
#include "draw_attributes.hh"
#include "draw_subdivision.h"
#include "extract_mesh.hh"

View File

@ -401,9 +401,9 @@ static void add_verts_to_dgroups(ReportList *reports,
vertsfilled = 1;
}
else if (BKE_modifiers_findby_type(ob, eModifierType_Subsurf)) {
/* is subsurf on? Lets use the verts on the limit surface then.
/* Is subdivision-surface on? Lets use the verts on the limit surface then.
* = same amount of vertices as mesh, but vertices moved to the
* subsurfed position, like for 'optimal'. */
* subdivision-surfaced position, like for 'optimal'. */
subsurf_calculate_limit_positions(mesh, verts);
vertsfilled = 1;
}

View File

@ -357,9 +357,9 @@ static void apply_selection_operation_at_index(GMutableSpan selection,
}
/**
* Helper struct for `find_closest_point_to_screen_co`.
* Helper struct for `select_pick`.
*/
struct FindClosestPointData {
struct FindClosestData {
int index = -1;
float distance = FLT_MAX;
};
@ -371,7 +371,7 @@ static bool find_closest_point_to_screen_co(const Depsgraph &depsgraph,
const bke::CurvesGeometry &curves,
float2 mouse_pos,
float radius,
FindClosestPointData &closest_data)
FindClosestData &closest_data)
{
float4x4 projection;
ED_view3d_ob_project_mat_get(rv3d, &object, projection.ptr());
@ -380,12 +380,12 @@ static bool find_closest_point_to_screen_co(const Depsgraph &depsgraph,
bke::crazyspace::get_evaluated_curves_deformation(depsgraph, object);
const float radius_sq = pow2f(radius);
auto [min_point_index, min_distance] = threading::parallel_reduce(
closest_data = threading::parallel_reduce(
curves.points_range(),
1024,
FindClosestPointData(),
[&](const IndexRange point_range, const FindClosestPointData &init) {
FindClosestPointData best_match = init;
FindClosestData(),
[&](const IndexRange point_range, const FindClosestData &init) {
FindClosestData best_match = init;
for (const int point_i : point_range) {
const float3 pos = deformation.positions[point_i];
@ -400,7 +400,7 @@ static bool find_closest_point_to_screen_co(const Depsgraph &depsgraph,
continue;
}
FindClosestPointData better_candidate;
FindClosestData better_candidate;
better_candidate.index = point_i;
better_candidate.distance = std::sqrt(distance_proj_sq);
@ -408,18 +408,104 @@ static bool find_closest_point_to_screen_co(const Depsgraph &depsgraph,
}
return best_match;
},
[](const FindClosestPointData &a, const FindClosestPointData &b) {
[](const FindClosestData &a, const FindClosestData &b) {
if (a.distance < b.distance) {
return a;
}
return b;
});
if (closest_data.index > 0) {
return true;
}
return false;
}
static bool find_closest_curve_to_screen_co(const Depsgraph &depsgraph,
const ARegion *region,
const RegionView3D *rv3d,
const Object &object,
const bke::CurvesGeometry &curves,
float2 mouse_pos,
float radius,
FindClosestData &closest_data)
{
float4x4 projection;
ED_view3d_ob_project_mat_get(rv3d, &object, projection.ptr());
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(depsgraph, object);
const float radius_sq = pow2f(radius);
const OffsetIndices points_by_curve = curves.points_by_curve();
closest_data = threading::parallel_reduce(
curves.curves_range(),
256,
FindClosestData(),
[&](const IndexRange curves_range, const FindClosestData &init) {
FindClosestData best_match = init;
for (const int curve_i : curves_range) {
if (points_by_curve.size(curve_i) == 1) {
const float3 pos = deformation.positions[points_by_curve[curve_i].first()];
/* Find the position of the point in screen space. */
float2 pos_proj;
ED_view3d_project_float_v2_m4(region, pos, pos_proj, projection.ptr());
const float distance_proj_sq = math::distance_squared(pos_proj, mouse_pos);
if (distance_proj_sq > radius_sq ||
distance_proj_sq > best_match.distance * best_match.distance) {
/* Ignore the point because it's too far away or there is already a better point.
*/
continue;
}
FindClosestData better_candidate;
better_candidate.index = curve_i;
better_candidate.distance = std::sqrt(distance_proj_sq);
best_match = better_candidate;
continue;
}
for (const int segment_i : points_by_curve[curve_i].drop_back(1)) {
const float3 pos1 = deformation.positions[segment_i];
const float3 pos2 = deformation.positions[segment_i + 1];
float2 pos1_proj, pos2_proj;
ED_view3d_project_float_v2_m4(region, pos1, pos1_proj, projection.ptr());
ED_view3d_project_float_v2_m4(region, pos2, pos2_proj, projection.ptr());
const float distance_proj_sq = dist_squared_to_line_segment_v2(
mouse_pos, pos1_proj, pos2_proj);
if (distance_proj_sq > radius_sq ||
distance_proj_sq > best_match.distance * best_match.distance) {
/* Ignore the segment because it's too far away or there is already a better point.
*/
continue;
}
FindClosestData better_candidate;
better_candidate.index = curve_i;
better_candidate.distance = std::sqrt(distance_proj_sq);
best_match = better_candidate;
}
}
return best_match;
},
[](const FindClosestData &a, const FindClosestData &b) {
if (a.distance < b.distance) {
return a;
}
return b;
});
if (min_point_index > 0) {
closest_data.index = min_point_index;
closest_data.distance = min_distance;
if (closest_data.index > 0) {
return true;
}
return false;
}
@ -429,15 +515,28 @@ bool select_pick(const ViewContext &vc,
const SelectPick_Params &params,
const int2 coord)
{
FindClosestPointData closest_point;
bool found = find_closest_point_to_screen_co(*vc.depsgraph,
vc.region,
vc.rv3d,
*vc.obact,
curves,
float2(coord),
ED_view3d_select_dist_px(),
closest_point);
FindClosestData closest;
bool found = false;
if (selection_domain == ATTR_DOMAIN_POINT) {
found = find_closest_point_to_screen_co(*vc.depsgraph,
vc.region,
vc.rv3d,
*vc.obact,
curves,
float2(coord),
ED_view3d_select_dist_px(),
closest);
}
else if (selection_domain == ATTR_DOMAIN_CURVE) {
found = find_closest_curve_to_screen_co(*vc.depsgraph,
vc.region,
vc.rv3d,
*vc.obact,
curves,
float2(coord),
ED_view3d_select_dist_px(),
closest);
}
bool changed = false;
if (params.sel_op == SEL_OP_SET) {
@ -453,17 +552,7 @@ bool select_pick(const ViewContext &vc,
if (found) {
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
int elem_index = closest_point.index;
if (selection_domain == ATTR_DOMAIN_CURVE) {
/* Find the curve index for the found point. */
auto it = std::upper_bound(
curves.offsets().begin(), curves.offsets().end(), closest_point.index);
BLI_assert(it != curves.offsets().end());
elem_index = std::distance(curves.offsets().begin(), it) - 1;
}
apply_selection_operation_at_index(selection.span, elem_index, params.sel_op);
apply_selection_operation_at_index(selection.span, closest.index, params.sel_op);
selection.finish();
}
@ -507,13 +596,29 @@ bool select_box(const ViewContext &vc,
else if (selection_domain == ATTR_DOMAIN_CURVE) {
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) {
for (const int curve_i : curves_range) {
for (const int point_i : points_by_curve[curve_i]) {
if (points_by_curve.size(curve_i) == 1) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region,
deformation.positions[points_by_curve[curve_i].first()],
pos_proj,
projection.ptr());
if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
}
continue;
}
for (const int segment_i : points_by_curve[curve_i].drop_back(1)) {
const float3 pos1 = deformation.positions[segment_i];
const float3 pos2 = deformation.positions[segment_i + 1];
float2 pos1_proj, pos2_proj;
ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region, pos2, pos2_proj, projection.ptr());
if (BLI_rcti_isect_segment(&rect, int2(pos1_proj), int2(pos2_proj))) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
break;
}
}
@ -569,16 +674,40 @@ bool select_lasso(const ViewContext &vc,
else if (selection_domain == ATTR_DOMAIN_CURVE) {
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) {
for (const int curve_i : curves_range) {
for (const int point_i : points_by_curve[curve_i]) {
if (points_by_curve.size(curve_i) == 1) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region,
deformation.positions[points_by_curve[curve_i].first()],
pos_proj,
projection.ptr());
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) &&
BLI_lasso_is_point_inside(
coord_array, coords.size(), int(pos_proj.x), int(pos_proj.y), IS_CLIPPED)) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
}
continue;
}
for (const int segment_i : points_by_curve[curve_i].drop_back(1)) {
const float3 pos1 = deformation.positions[segment_i];
const float3 pos2 = deformation.positions[segment_i + 1];
float2 pos1_proj, pos2_proj;
ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region, pos2, pos2_proj, projection.ptr());
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_segment(&bbox, int2(pos1_proj), int2(pos2_proj)) &&
BLI_lasso_is_edge_inside(coord_array,
coords.size(),
int(pos1_proj.x),
int(pos1_proj.y),
int(pos2_proj.x),
int(pos2_proj.y),
IS_CLIPPED)) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
break;
}
}
@ -629,13 +758,31 @@ bool select_circle(const ViewContext &vc,
else if (selection_domain == ATTR_DOMAIN_CURVE) {
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) {
for (const int curve_i : curves_range) {
for (const int point_i : points_by_curve[curve_i]) {
if (points_by_curve.size(curve_i) == 1) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region,
deformation.positions[points_by_curve[curve_i].first()],
pos_proj,
projection.ptr());
if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
}
continue;
}
for (const int segment_i : points_by_curve[curve_i].drop_back(1)) {
const float3 pos1 = deformation.positions[segment_i];
const float3 pos2 = deformation.positions[segment_i + 1];
float2 pos1_proj, pos2_proj;
ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region, pos2, pos2_proj, projection.ptr());
const float distance_proj_sq = dist_squared_to_line_segment_v2(
float2(coord), pos1_proj, pos2_proj);
if (distance_proj_sq <= radius_sq) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
break;
}
}

View File

@ -528,7 +528,7 @@ static short annotation_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(pt->m_xy, mval);
/* #44932 - Pressure vals are unreliable, so ignore for now */
/* Pressure values are unreliable, so ignore for now, see #44932. */
pt->pressure = 1.0f;
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);
@ -544,7 +544,7 @@ static short annotation_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(pt->m_xy, mval);
/* #44932 - Pressure vals are unreliable, so ignore for now */
/* Pressure values are unreliable, so ignore for now, see #44932. */
pt->pressure = 1.0f;
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);
@ -620,7 +620,7 @@ static short annotation_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(pt->m_xy, mval);
/* #44932 - Pressure vals are unreliable, so ignore for now */
/* Pressure values are unreliable, so ignore for now, see #44932. */
pt->pressure = 1.0f;
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);

View File

@ -4059,12 +4059,11 @@ void GPENCIL_OT_reproject(wmOperatorType *ot)
ot->prop = RNA_def_enum(
ot->srna, "type", reproject_type, GP_REPROJECT_VIEW, "Projection Type", "");
prop = RNA_def_boolean(
ot->srna,
"keep_original",
0,
"Keep Original",
"Keep original strokes and create a copy before reprojecting instead of reproject them");
prop = RNA_def_boolean(ot->srna,
"keep_original",
0,
"Keep Original",
"Keep original strokes and create a copy before reprojecting");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MOVIECLIP);
RNA_def_float(ot->srna, "offset", 0.0f, 0.0f, 10.0f, "Surface Offset", "", 0.0f, 10.0f);
@ -4771,7 +4770,7 @@ void GPENCIL_OT_stroke_simplify(wmOperatorType *ot)
/* identifiers */
ot->name = "Simplify Stroke";
ot->idname = "GPENCIL_OT_stroke_simplify";
ot->description = "Simplify selected stroked reducing number of points";
ot->description = "Simplify selected strokes, reducing number of points";
/* api callbacks */
ot->exec = gpencil_stroke_simplify_exec;
@ -4832,7 +4831,7 @@ void GPENCIL_OT_stroke_simplify_fixed(wmOperatorType *ot)
/* identifiers */
ot->name = "Simplify Fixed Stroke";
ot->idname = "GPENCIL_OT_stroke_simplify_fixed";
ot->description = "Simplify selected stroked reducing number of points using fixed algorithm";
ot->description = "Simplify selected strokes, reducing number of points using fixed algorithm";
/* api callbacks */
ot->exec = gpencil_stroke_simplify_fixed_exec;

View File

@ -188,7 +188,7 @@ void GPENCIL_OT_stroke_editcurve_set_handle_type(wmOperatorType *ot)
/* identifiers */
ot->name = "Set handle type";
ot->idname = "GPENCIL_OT_stroke_editcurve_set_handle_type";
ot->description = "Set the type of a edit curve handle";
ot->description = "Set the type of an edit curve handle";
/* api callbacks */
ot->invoke = WM_menu_invoke;

View File

@ -764,7 +764,7 @@ static short gpencil_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(pt->m_xy, mval);
/* #44932 - Pressure vals are unreliable, so ignore for now */
/* Pressure values are unreliable, so ignore for now, see #44932. */
pt->pressure = 1.0f;
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);
@ -780,7 +780,7 @@ static short gpencil_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(pt->m_xy, mval);
/* #44932 - Pressure vals are unreliable, so ignore for now */
/* Pressure values are unreliable, so ignore for now, see #44932. */
pt->pressure = 1.0f;
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);
@ -3685,7 +3685,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
/* We don't pass on key events, GP is used with key-modifiers -
* prevents Dkey to insert drivers. */
* prevents D-key to insert drivers. */
if (ISKEYBOARD(event->type)) {
if (ELEM(event->type, EVT_LEFTARROWKEY, EVT_DOWNARROWKEY, EVT_RIGHTARROWKEY, EVT_UPARROWKEY)) {
/* allow some keys:

View File

@ -75,7 +75,7 @@ const EnumPropertyItem rna_enum_usd_mtl_name_collision_mode_items[] = {
const EnumPropertyItem rna_enum_usd_tex_import_mode_items[] = {
{USD_TEX_IMPORT_NONE, "IMPORT_NONE", 0, "None", "Don't import textures"},
{USD_TEX_IMPORT_PACK, "IMPORT_PACK", 0, "Packed", "Import textures as packed data"},
{USD_TEX_IMPORT_COPY, "IMPORT_COPY", 0, "Copy", "Copy files to Textures Directory"},
{USD_TEX_IMPORT_COPY, "IMPORT_COPY", 0, "Copy", "Copy files to textures directory"},
{0, NULL, 0, NULL, NULL},
};
@ -382,6 +382,7 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
const bool import_materials = RNA_boolean_get(op->ptr, "import_materials");
const bool import_meshes = RNA_boolean_get(op->ptr, "import_meshes");
const bool import_volumes = RNA_boolean_get(op->ptr, "import_volumes");
const bool import_shapes = RNA_boolean_get(op->ptr, "import_shapes");
const bool import_subdiv = RNA_boolean_get(op->ptr, "import_subdiv");
@ -443,6 +444,7 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
.import_materials = import_materials,
.import_meshes = import_meshes,
.import_volumes = import_volumes,
.import_shapes = import_shapes,
.import_subdiv = import_subdiv,
.import_instance_proxies = import_instance_proxies,
.create_collection = create_collection,
@ -488,6 +490,7 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op)
uiItemR(col, ptr, "import_materials", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "import_meshes", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "import_volumes", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "import_shapes", 0, NULL, ICON_NONE);
uiItemR(box, ptr, "prim_path_mask", 0, NULL, ICON_NONE);
uiItemR(box, ptr, "scale", 0, NULL, ICON_NONE);
@ -577,6 +580,7 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
RNA_def_boolean(ot->srna, "import_materials", true, "Materials", "");
RNA_def_boolean(ot->srna, "import_meshes", true, "Meshes", "");
RNA_def_boolean(ot->srna, "import_volumes", true, "Volumes", "");
RNA_def_boolean(ot->srna, "import_shapes", true, "Shapes", "");
RNA_def_boolean(ot->srna,
"import_subdiv",
@ -675,7 +679,7 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
"//textures/",
FILE_MAXDIR,
"Textures Directory",
"Path to the directory where imported textures will be copied ");
"Path to the directory where imported textures will be copied");
RNA_def_enum(
ot->srna,

View File

@ -54,7 +54,7 @@ typedef struct {
BMBackup mesh_backup;
bool is_valid;
bool is_dirty;
} * backup;
} *backup;
int backup_len;
} BisectData;
@ -528,15 +528,7 @@ static void gizmo_mesh_bisect_update_from_op(GizmoGroup *ggd)
normalize_v3(ggd->data.rotate_up);
WM_gizmo_set_matrix_rotation_from_z_axis(ggd->translate_c, plane_no);
float plane_no_cross[3];
cross_v3_v3v3(plane_no_cross, plane_no, ggd->data.rotate_axis);
WM_gizmo_set_matrix_offset_rotation_from_yz_axis(
ggd->rotate_c, plane_no_cross, ggd->data.rotate_axis);
RNA_enum_set(ggd->rotate_c->ptr,
"draw_options",
ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR | ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y);
WM_gizmo_set_matrix_rotation_from_z_axis(ggd->rotate_c, ggd->data.rotate_axis);
}
}

View File

@ -410,7 +410,7 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan<bool> select_poly = attributes.lookup_or_default<bool>(
".select_poly", ATTR_DOMAIN_FACE, false);
threading::parallel_for(IndexRange(mesh->totvert), 4096, [&](const IndexRange range) {
threading::parallel_for(select_poly.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
if (select_poly[i]) {
ss->face_sets[i] = next_face_set;

View File

@ -50,83 +50,84 @@
#define MARK_BOUNDARY 1
typedef struct UvAdjacencyElement {
/* pointer to original uvelement */
/** pointer to original UV-element. */
UvElement *element;
/* uv pointer for convenience. Caution, this points to the original UVs! */
/** UV pointer for convenience. Caution, this points to the original UVs! */
float *uv;
/* Are we on locked in place? */
/** Are we on locked in place? */
bool is_locked;
/* Are we on the boundary? */
/** Are we on the boundary? */
bool is_boundary;
} UvAdjacencyElement;
typedef struct UvEdge {
uint uv1;
uint uv2;
/* Are we in the interior? */
/** Are we in the interior? */
bool is_interior;
} UvEdge;
typedef struct UVInitialStrokeElement {
/* index to unique uv */
/** index to unique UV. */
int uv;
/* strength of brush on initial position */
/** Strength of brush on initial position. */
float strength;
/* initial uv position */
/** initial UV position. */
float initial_uv[2];
} UVInitialStrokeElement;
typedef struct UVInitialStroke {
/* Initial Selection,for grab brushes for instance */
/** Initial Selection,for grab brushes for instance. */
UVInitialStrokeElement *initialSelection;
/* Total initially selected UVs. */
/** Total initially selected UVs. */
int totalInitialSelected;
/* initial mouse coordinates */
/** Initial mouse coordinates. */
float init_coord[2];
} UVInitialStroke;
/* custom data for uv smoothing brush */
/** Custom data for UV smoothing brush. */
typedef struct UvSculptData {
/* Contains the first of each set of coincident UVs.
* These will be used to perform smoothing on and propagate the changes
* to their coincident UVs */
/**
* Contains the first of each set of coincident UVs.
* These will be used to perform smoothing on and propagate the changes to their coincident UVs.
*/
UvAdjacencyElement *uv;
/* Total number of unique UVs. */
/** Total number of unique UVs. */
int totalUniqueUvs;
/* Edges used for adjacency info, used with laplacian smoothing */
/** Edges used for adjacency info, used with laplacian smoothing */
UvEdge *uvedges;
/* Total number of #UvEdge. */
/** Total number of #UvEdge. */
int totalUvEdges;
/* data for initial stroke, used by tools like grab */
/** data for initial stroke, used by tools like grab */
UVInitialStroke *initial_stroke;
/* timer to be used for airbrush-type brush */
/** Timer to be used for airbrush-type brush. */
wmTimer *timer;
/* to determine quickly adjacent UVs */
/** To determine quickly adjacent UVs. */
UvElementMap *elementMap;
/* uvsmooth Paint for fast reference */
/** UV-smooth Paint for fast reference. */
Paint *uvsculpt;
/* tool to use. duplicating here to change if modifier keys are pressed */
/** Tool to use. duplicating here to change if modifier keys are pressed. */
char tool;
/* store invert flag here */
/** Store invert flag here. */
char invert;
/* Is constrain to image bounds active? */
/** Is constrain to image bounds active? */
bool constrain_to_bounds;
/* Base for constrain_to_bounds. */
/** Base for constrain_to_bounds. */
float uv_base_offset[2];
} UvSculptData;

View File

@ -586,7 +586,7 @@ void ED_animedit_unlink_action(
if (strip->act == act) {
/* Remove this strip, and the track too if it doesn't have anything else */
BKE_nlastrip_free(&nlt->strips, strip, true);
BKE_nlastrip_remove_and_free(&nlt->strips, strip, true);
if (nlt->strips.first == NULL) {
BLI_assert(nstrip == NULL);

View File

@ -986,7 +986,7 @@ void file_draw_list(const bContext *C, ARegion *region)
UI_GetThemeColor4ubv(TH_TEXT, text_col);
for (i = offset; (i < numfiles) && (i < offset + numfiles_layout); i++) {
uint file_selflag;
eDirEntry_SelectFlag file_selflag;
const int padx = 0.1f * UI_UNIT_X;
int icon_ofs = 0;

View File

@ -137,7 +137,7 @@ FileAttributeColumnType file_attribute_column_type_find_isect(const View2D *v2d,
float file_string_width(const char *str);
float file_font_pointsize(void);
void file_select_deselect_all(SpaceFile *sfile, uint flag);
void file_select_deselect_all(SpaceFile *sfile, eDirEntry_SelectFlag flag);
int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file);
int autocomplete_directory(struct bContext *C, char *str, void *arg_v);
int autocomplete_file(struct bContext *C, char *str, void *arg_v);

View File

@ -233,11 +233,15 @@ struct FileList {
FileListEntryCache filelist_cache;
/* We need to keep those info outside of actual filelist items,
/**
* We need to keep those info outside of actual file-list items,
* because those are no more persistent
* (only generated on demand, and freed as soon as possible).
* Persistent part (mere list of paths + stat info)
* is kept as small as possible, and file-browser agnostic.
*
* - The key is a #FileDirEntry::uid
* - The value is an #eDirEntry_SelectFlag.
*/
GHash *selection_state;
@ -2737,13 +2741,13 @@ int filelist_needs_reading(FileList *filelist)
uint filelist_entry_select_set(const FileList *filelist,
const FileDirEntry *entry,
FileSelType select,
uint flag,
const eDirEntry_SelectFlag flag,
FileCheckType check)
{
/* Default nullptr pointer if not found is fine here! */
void **es_p = BLI_ghash_lookup_p(filelist->selection_state, POINTER_FROM_UINT(entry->uid));
uint entry_flag = es_p ? POINTER_AS_UINT(*es_p) : 0;
const uint org_entry_flag = entry_flag;
eDirEntry_SelectFlag entry_flag = eDirEntry_SelectFlag(es_p ? POINTER_AS_UINT(*es_p) : 0);
const eDirEntry_SelectFlag org_entry_flag = entry_flag;
BLI_assert(entry);
BLI_assert(ELEM(check, CHECK_DIRS, CHECK_FILES, CHECK_ALL));
@ -2782,8 +2786,11 @@ uint filelist_entry_select_set(const FileList *filelist,
return entry_flag;
}
void filelist_entry_select_index_set(
FileList *filelist, const int index, FileSelType select, uint flag, FileCheckType check)
void filelist_entry_select_index_set(FileList *filelist,
const int index,
FileSelType select,
const eDirEntry_SelectFlag flag,
FileCheckType check)
{
FileDirEntry *entry = filelist_file(filelist, index);
@ -2792,8 +2799,11 @@ void filelist_entry_select_index_set(
}
}
void filelist_entries_select_index_range_set(
FileList *filelist, FileSelection *sel, FileSelType select, uint flag, FileCheckType check)
void filelist_entries_select_index_range_set(FileList *filelist,
FileSelection *sel,
FileSelType select,
const eDirEntry_SelectFlag flag,
FileCheckType check)
{
/* select all valid files between first and last indicated */
if ((sel->first >= 0) && (sel->first < filelist->filelist.entries_filtered_num) &&
@ -2805,7 +2815,9 @@ void filelist_entries_select_index_range_set(
}
}
uint filelist_entry_select_get(FileList *filelist, FileDirEntry *entry, FileCheckType check)
eDirEntry_SelectFlag filelist_entry_select_get(FileList *filelist,
FileDirEntry *entry,
FileCheckType check)
{
BLI_assert(entry);
BLI_assert(ELEM(check, CHECK_DIRS, CHECK_FILES, CHECK_ALL));
@ -2813,14 +2825,16 @@ uint filelist_entry_select_get(FileList *filelist, FileDirEntry *entry, FileChec
if ((check == CHECK_ALL) || ((check == CHECK_DIRS) && (entry->typeflag & FILE_TYPE_DIR)) ||
((check == CHECK_FILES) && !(entry->typeflag & FILE_TYPE_DIR))) {
/* Default nullptr pointer if not found is fine here! */
return POINTER_AS_UINT(
BLI_ghash_lookup(filelist->selection_state, POINTER_FROM_UINT(entry->uid)));
return eDirEntry_SelectFlag(POINTER_AS_UINT(
BLI_ghash_lookup(filelist->selection_state, POINTER_FROM_UINT(entry->uid))));
}
return 0;
return eDirEntry_SelectFlag(0);
}
uint filelist_entry_select_index_get(FileList *filelist, const int index, FileCheckType check)
eDirEntry_SelectFlag filelist_entry_select_index_get(FileList *filelist,
const int index,
FileCheckType check)
{
FileDirEntry *entry = filelist_file(filelist, index);
@ -2828,7 +2842,7 @@ uint filelist_entry_select_index_get(FileList *filelist, const int index, FileCh
return filelist_entry_select_get(filelist, entry, check);
}
return 0;
return eDirEntry_SelectFlag(0);
}
bool filelist_entry_is_selected(FileList *filelist, const int index)
@ -2838,15 +2852,15 @@ bool filelist_entry_is_selected(FileList *filelist, const int index)
/* BLI_ghash_lookup returns nullptr if not found, which gets mapped to 0, which gets mapped to
* "not selected". */
const uint selection_state = POINTER_AS_UINT(
BLI_ghash_lookup(filelist->selection_state, POINTER_FROM_UINT(intern_entry->uid)));
const eDirEntry_SelectFlag selection_state = eDirEntry_SelectFlag(POINTER_AS_UINT(
BLI_ghash_lookup(filelist->selection_state, POINTER_FROM_UINT(intern_entry->uid))));
return selection_state != 0;
}
void filelist_entry_parent_select_set(FileList *filelist,
FileSelType select,
uint flag,
const eDirEntry_SelectFlag flag,
FileCheckType check)
{
if ((filelist->filter_data.flags & FLF_HIDE_PARENT) == 0) {

View File

@ -148,31 +148,31 @@ bool filelist_is_ready(struct FileList *filelist);
unsigned int filelist_entry_select_set(const struct FileList *filelist,
const struct FileDirEntry *entry,
FileSelType select,
unsigned int flag,
const eDirEntry_SelectFlag flag,
FileCheckType check);
void filelist_entry_select_index_set(struct FileList *filelist,
int index,
FileSelType select,
unsigned int flag,
eDirEntry_SelectFlag flag,
FileCheckType check);
void filelist_entries_select_index_range_set(struct FileList *filelist,
FileSelection *sel,
FileSelType select,
unsigned int flag,
FileCheckType check);
unsigned int filelist_entry_select_get(struct FileList *filelist,
struct FileDirEntry *entry,
FileCheckType check);
unsigned int filelist_entry_select_index_get(struct FileList *filelist,
int index,
eDirEntry_SelectFlag flag,
FileCheckType check);
eDirEntry_SelectFlag filelist_entry_select_get(struct FileList *filelist,
struct FileDirEntry *entry,
FileCheckType check);
eDirEntry_SelectFlag filelist_entry_select_index_get(struct FileList *filelist,
int index,
FileCheckType check);
bool filelist_entry_is_selected(struct FileList *filelist, int index);
/**
* Set selection of the '..' parent entry, but only if it's actually visible.
*/
void filelist_entry_parent_select_set(struct FileList *filelist,
FileSelType select,
unsigned int flag,
eDirEntry_SelectFlag flag,
FileCheckType check);
void filelist_setrecursion(struct FileList *filelist, int recursion_level);

View File

@ -1124,7 +1124,7 @@ void ED_file_change_dir(bContext *C)
ED_file_change_dir_ex(C, area);
}
void file_select_deselect_all(SpaceFile *sfile, uint flag)
void file_select_deselect_all(SpaceFile *sfile, const eDirEntry_SelectFlag flag)
{
FileSelection sel;
sel.first = 0;

View File

@ -1305,15 +1305,15 @@ static int nlaedit_delete_exec(bContext *C, wmOperator *UNUSED(op))
if (strip->flag & NLASTRIP_FLAG_SELECT) {
/* if a strip either side of this was a transition, delete those too */
if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION)) {
BKE_nlastrip_free(&nlt->strips, strip->prev, true);
BKE_nlastrip_remove_and_free(&nlt->strips, strip->prev, true);
}
if ((nstrip) && (nstrip->type == NLASTRIP_TYPE_TRANSITION)) {
nstrip = nstrip->next;
BKE_nlastrip_free(&nlt->strips, strip->next, true);
BKE_nlastrip_remove_and_free(&nlt->strips, strip->next, true);
}
/* finally, delete this strip */
BKE_nlastrip_free(&nlt->strips, strip, true);
BKE_nlastrip_remove_and_free(&nlt->strips, strip, true);
}
}
}
@ -1824,7 +1824,7 @@ static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op))
if (BKE_nlatrack_has_space(nltn, strip->start, strip->end)) {
/* remove from its current track, and add to the one above
* (it 'should' work, so no need to worry) */
BLI_remlink(&nlt->strips, strip);
BKE_nlatrack_remove_strip(nlt, strip);
BKE_nlatrack_add_strip(nltn, strip, is_liboverride);
}
}
@ -1916,7 +1916,7 @@ static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op))
if (BKE_nlatrack_has_space(nltp, strip->start, strip->end)) {
/* remove from its current track, and add to the one above
* (it 'should' work, so no need to worry) */
BLI_remlink(&nlt->strips, strip);
BKE_nlatrack_remove_strip(nlt, strip);
BKE_nlatrack_add_strip(nltp, strip, is_liboverride);
}
}

View File

@ -148,7 +148,7 @@ static bool node_under_mouse_tweak(const bNodeTree &ntree, const float2 &mouse)
switch (node->type) {
case NODE_REROUTE: {
const float2 location = node_to_view(*node, {node->locx, node->locy});
if (math::distance(mouse, location) < 24.0f) {
if (math::distance_squared(mouse, location) < square_f(24.0f)) {
return true;
}
break;

View File

@ -457,7 +457,7 @@ static void recalcData_nla(TransInfo *t)
if (BKE_nlatrack_has_space(track, strip->start, strip->end) &&
!BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, track)) {
/* move strip to this track */
BLI_remlink(&tdn->nlt->strips, strip);
BKE_nlatrack_remove_strip(tdn->nlt, strip);
BKE_nlatrack_add_strip(track, strip, is_liboverride);
tdn->nlt = track;
@ -477,7 +477,7 @@ static void recalcData_nla(TransInfo *t)
if (BKE_nlatrack_has_space(track, strip->start, strip->end) &&
!BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, track)) {
/* move strip to this track */
BLI_remlink(&tdn->nlt->strips, strip);
BKE_nlatrack_remove_strip(tdn->nlt, strip);
BKE_nlatrack_add_strip(track, strip, is_liboverride);
tdn->nlt = track;

View File

@ -50,15 +50,15 @@ static bool lib_id_preview_editing_poll(bContext *C)
return false;
}
if (ID_IS_LINKED(id)) {
CTX_wm_operator_poll_msg_set(C, TIP_("Can't edit external library data"));
CTX_wm_operator_poll_msg_set(C, "Can't edit external library data");
return false;
}
if (ID_IS_OVERRIDE_LIBRARY(id)) {
CTX_wm_operator_poll_msg_set(C, TIP_("Can't edit previews of overridden library data"));
CTX_wm_operator_poll_msg_set(C, "Can't edit previews of overridden library data");
return false;
}
if (!BKE_previewimg_id_get_p(id)) {
CTX_wm_operator_poll_msg_set(C, TIP_("Data-block does not support previews"));
CTX_wm_operator_poll_msg_set(C, "Data-block does not support previews");
return false;
}
@ -118,7 +118,7 @@ static bool lib_id_generate_preview_poll(bContext *C)
const PointerRNA idptr = CTX_data_pointer_get(C, "id");
const ID *id = (ID *)idptr.data;
if (GS(id->name) == ID_NT) {
CTX_wm_operator_poll_msg_set(C, TIP_("Can't generate automatic preview for node group"));
CTX_wm_operator_poll_msg_set(C, "Can't generate automatic preview for node group");
return false;
}

View File

@ -104,6 +104,7 @@ set(SRC
GPU_primitive.h
GPU_select.h
GPU_shader.h
GPU_shader_builtin.h
GPU_shader_shared.h
GPU_state.h
GPU_storage_buffer.h

View File

@ -249,8 +249,10 @@ typedef enum {
} GPUUniformBuiltin;
#define GPU_NUM_UNIFORMS (GPU_UNIFORM_SRGB_TRANSFORM + 1)
/** TODO: To be moved as private API. Not really used outside of gpu_matrix.cc and doesn't really
* offer a noticeable perf boost. */
/**
* TODO: To be moved as private API. Not really used outside of gpu_matrix.cc and doesn't really
* offer a noticeable performance boost.
*/
int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin);
/** DEPRECATED: Use hardcoded buffer location instead. */

View File

@ -11,6 +11,11 @@
typedef struct TestOutputRawData TestOutputRawData;
#endif
/* NOTE: float3 has differing stride and alignment rules across different GPU backends. If 12 byte
* stride and alignment is essential, use `packed_float3` to avoid data read issues. This is
* required in the common use-case where a float3 and an int/float are paired together for optimal
* data transfer. */
enum eGPUKeyframeShapes {
GPU_KEYFRAME_SHAPE_DIAMOND = (1u << 0u),
GPU_KEYFRAME_SHAPE_CIRCLE = (1u << 1u),
@ -70,7 +75,7 @@ BLI_STATIC_ASSERT_ALIGN(struct GPUClipPlanes, 16)
struct SimpleLightingData {
float4 l_color;
float3 light;
packed_float3 light;
float _pad;
};
BLI_STATIC_ASSERT_ALIGN(struct SimpleLightingData, 16)

View File

@ -59,6 +59,7 @@
# define bool2 bvec2
# define bool3 bvec3
# define bool4 bvec4
# define packed_float3 vec3
# endif
#else /* C / C++ */
@ -83,6 +84,7 @@ using bool1 = int;
using bool2 = blender::int2;
using bool3 = blender::int3;
using bool4 = blender::int4;
using packed_float3 = blender::float3;
# else /* C */
typedef float float2[2];
@ -99,6 +101,7 @@ typedef int bool1;
typedef int bool2[2];
typedef int bool3[2];
typedef int bool4[4];
typedef float3 packed_float3;
# endif
#endif

View File

@ -810,6 +810,8 @@ struct GPUSource {
}
dependencies.append_non_duplicates(dependency_source);
}
/* Precedes an eternal loop (quiet CLANG's `unreachable-code` warning). */
BLI_assert_unreachable();
return 0;
}

View File

@ -18,17 +18,17 @@ namespace blender::gpu {
/**
* `VK_ALLOCATION_CALLBACKS` initializes allocation callbacks for host allocations.
* The macro creates a local static variable with the name `vk_allocation_callbacks`
* that can be passed to vulkan API functions that expect
* that can be passed to VULKAN API functions that expect
* `const VkAllocationCallbacks *pAllocator`.
*
* When Blender is compiled with `WITH_VULKAN_GUARDEDALLOC` this will use
* `MEM_guardedalloc` for host allocations that the driver does on behalf
* of blender. More internal allocations are still being allocated via the
* implemention inside the vulkan device driver.
* implementation inside the VULKAN device driver.
*
* When `WITH_VULKAN_GUARDEDALLOC=Off` the memory allocation implemented
* in the vulkan device driver is used for both internal and application
* focussed memory operations.
* focused memory operations.
*/
#ifdef WITH_VULKAN_GUARDEDALLOC
@ -55,7 +55,8 @@ constexpr VkAllocationCallbacks vk_allocation_callbacks_init(const char *name)
# define VK_ALLOCATION_CALLBACKS \
static constexpr const VkAllocationCallbacks vk_allocation_callbacks_ = \
vk_allocation_callbacks_init(__func__); \
static constexpr const VkAllocationCallbacks *vk_allocation_callbacks = &vk_allocation_callbacks_;
static constexpr const VkAllocationCallbacks *vk_allocation_callbacks = \
&vk_allocation_callbacks_;
#else
# define VK_ALLOCATION_CALLBACKS \
static constexpr const VkAllocationCallbacks *vk_allocation_callbacks = nullptr;

View File

@ -83,6 +83,7 @@ set(SRC
intern/usd_reader_mesh.cc
intern/usd_reader_nurbs.cc
intern/usd_reader_prim.cc
intern/usd_reader_shape.cc
intern/usd_reader_stage.cc
intern/usd_reader_volume.cc
intern/usd_reader_xform.cc
@ -111,6 +112,7 @@ set(SRC
intern/usd_reader_mesh.h
intern/usd_reader_nurbs.h
intern/usd_reader_prim.h
intern/usd_reader_shape.h
intern/usd_reader_stage.h
intern/usd_reader_volume.h
intern/usd_reader_xform.h
@ -145,8 +147,8 @@ blender_add_lib(bf_usd "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
if(WITH_GTESTS)
set(TEST_SRC
tests/usd_stage_creation_test.cc
tests/usd_export_test.cc
tests/usd_stage_creation_test.cc
tests/usd_tests_common.cc
tests/usd_tests_common.h

View File

@ -0,0 +1,245 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2023 Nvidia. All rights reserved. */
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "DNA_cachefile_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_windowmanager_types.h"
#include "WM_api.h"
#include "usd_reader_shape.h"
#include <pxr/usd/usdGeom/capsule.h>
#include <pxr/usd/usdGeom/cone.h>
#include <pxr/usd/usdGeom/cube.h>
#include <pxr/usd/usdGeom/cylinder.h>
#include <pxr/usd/usdGeom/sphere.h>
#include <pxr/usdImaging/usdImaging/capsuleAdapter.h>
#include <pxr/usdImaging/usdImaging/coneAdapter.h>
#include <pxr/usdImaging/usdImaging/cubeAdapter.h>
#include <pxr/usdImaging/usdImaging/cylinderAdapter.h>
#include <pxr/usdImaging/usdImaging/sphereAdapter.h>
namespace blender::io::usd {
USDShapeReader::USDShapeReader(const pxr::UsdPrim &prim,
const USDImportParams &import_params,
const ImportSettings &settings)
: USDGeomReader(prim, import_params, settings)
{
}
void USDShapeReader::create_object(Main *bmain, double /*motionSampleTime*/)
{
Mesh *mesh = BKE_mesh_add(bmain, name_.c_str());
object_ = BKE_object_add_only_object(bmain, OB_MESH, name_.c_str());
object_->data = mesh;
}
void USDShapeReader::read_object_data(Main *bmain, double motionSampleTime)
{
Mesh *mesh = (Mesh *)object_->data;
Mesh *read_mesh = this->read_mesh(
mesh, motionSampleTime, import_params_.mesh_read_flag, nullptr);
if (read_mesh != mesh) {
BKE_mesh_nomain_to_mesh(read_mesh, mesh, object_);
if (is_time_varying()) {
USDGeomReader::add_cache_modifier();
}
}
USDXformReader::read_object_data(bmain, motionSampleTime);
}
template<typename Adapter>
void USDShapeReader::read_values(const double motionSampleTime,
pxr::VtVec3fArray &positions,
pxr::VtIntArray &face_indices,
pxr::VtIntArray &face_counts) const
{
Adapter adapter;
pxr::VtValue points_val = adapter.GetPoints(prim_, motionSampleTime);
if (points_val.IsHolding<pxr::VtVec3fArray>()) {
positions = points_val.Get<pxr::VtVec3fArray>();
}
pxr::VtValue topology_val = adapter.GetTopology(prim_, pxr::SdfPath(), motionSampleTime);
if (topology_val.IsHolding<pxr::HdMeshTopology>()) {
const pxr::HdMeshTopology &topology = topology_val.Get<pxr::HdMeshTopology>();
face_counts = topology.GetFaceVertexCounts();
face_indices = topology.GetFaceVertexIndices();
}
}
bool USDShapeReader::read_mesh_values(double motionSampleTime,
pxr::VtVec3fArray &positions,
pxr::VtIntArray &face_indices,
pxr::VtIntArray &face_counts) const
{
if (prim_.IsA<pxr::UsdGeomCapsule>()) {
read_values<pxr::UsdImagingCapsuleAdapter>(
motionSampleTime, positions, face_indices, face_counts);
return true;
}
if (prim_.IsA<pxr::UsdGeomCylinder>()) {
read_values<pxr::UsdImagingCylinderAdapter>(
motionSampleTime, positions, face_indices, face_counts);
return true;
}
if (prim_.IsA<pxr::UsdGeomCone>()) {
read_values<pxr::UsdImagingConeAdapter>(
motionSampleTime, positions, face_indices, face_counts);
return true;
}
if (prim_.IsA<pxr::UsdGeomCube>()) {
read_values<pxr::UsdImagingCubeAdapter>(
motionSampleTime, positions, face_indices, face_counts);
return true;
}
if (prim_.IsA<pxr::UsdGeomSphere>()) {
read_values<pxr::UsdImagingSphereAdapter>(
motionSampleTime, positions, face_indices, face_counts);
return true;
}
WM_reportf(RPT_ERROR,
"Unhandled Gprim type: %s (%s)",
prim_.GetTypeName().GetText(),
prim_.GetPath().GetText());
return false;
}
Mesh *USDShapeReader::read_mesh(struct Mesh *existing_mesh,
double motionSampleTime,
int /*read_flag*/,
const char ** /*err_str*/)
{
pxr::VtIntArray face_indices;
pxr::VtIntArray face_counts;
if (!prim_) {
return existing_mesh;
}
/* Should have a good set of data by this point-- copy over. */
Mesh *active_mesh = mesh_from_prim(existing_mesh, motionSampleTime, face_indices, face_counts);
if (active_mesh == existing_mesh) {
return existing_mesh;
}
MutableSpan<MPoly> polys = active_mesh->polys_for_write();
MutableSpan<MLoop> loops = active_mesh->loops_for_write();
const char should_smooth = prim_.IsA<pxr::UsdGeomCube>() ? 0 : ME_SMOOTH;
int loop_index = 0;
for (int i = 0; i < face_counts.size(); i++) {
const int face_size = face_counts[i];
MPoly &poly = polys[i];
poly.loopstart = loop_index;
poly.totloop = face_size;
/* Don't smooth-shade cubes; we're not worrying about sharpness for Gprims. */
poly.flag |= should_smooth;
for (int f = 0; f < face_size; ++f, ++loop_index) {
loops[loop_index].v = face_indices[loop_index];
}
}
BKE_mesh_calc_edges(active_mesh, false, false);
return active_mesh;
}
Mesh *USDShapeReader::mesh_from_prim(Mesh *existing_mesh,
double motionSampleTime,
pxr::VtIntArray &face_indices,
pxr::VtIntArray &face_counts) const
{
pxr::VtVec3fArray positions;
if (!read_mesh_values(motionSampleTime, positions, face_indices, face_counts)) {
return existing_mesh;
}
const bool poly_counts_match = existing_mesh ? face_counts.size() == existing_mesh->totpoly :
false;
const bool position_counts_match = existing_mesh ? positions.size() == existing_mesh->totvert :
false;
Mesh *active_mesh = nullptr;
if (!position_counts_match || !poly_counts_match) {
active_mesh = BKE_mesh_new_nomain_from_template(
existing_mesh, positions.size(), 0, 0, face_indices.size(), face_counts.size());
}
else {
active_mesh = existing_mesh;
}
MutableSpan<float3> vert_positions = active_mesh->vert_positions_for_write();
for (int i = 0; i < positions.size(); i++) {
vert_positions[i][0] = positions[i][0];
vert_positions[i][1] = positions[i][1];
vert_positions[i][2] = positions[i][2];
}
return active_mesh;
}
bool USDShapeReader::is_time_varying()
{
if (prim_.IsA<pxr::UsdGeomCapsule>()) {
pxr::UsdGeomCapsule geom(prim_);
return (geom.GetAxisAttr().ValueMightBeTimeVarying() ||
geom.GetHeightAttr().ValueMightBeTimeVarying() ||
geom.GetRadiusAttr().ValueMightBeTimeVarying());
}
if (prim_.IsA<pxr::UsdGeomCylinder>()) {
pxr::UsdGeomCylinder geom(prim_);
return (geom.GetAxisAttr().ValueMightBeTimeVarying() ||
geom.GetHeightAttr().ValueMightBeTimeVarying() ||
geom.GetRadiusAttr().ValueMightBeTimeVarying());
}
if (prim_.IsA<pxr::UsdGeomCone>()) {
pxr::UsdGeomCone geom(prim_);
return (geom.GetAxisAttr().ValueMightBeTimeVarying() ||
geom.GetHeightAttr().ValueMightBeTimeVarying() ||
geom.GetRadiusAttr().ValueMightBeTimeVarying());
}
if (prim_.IsA<pxr::UsdGeomCube>()) {
pxr::UsdGeomCube geom(prim_);
return geom.GetSizeAttr().ValueMightBeTimeVarying();
}
if (prim_.IsA<pxr::UsdGeomSphere>()) {
pxr::UsdGeomSphere geom(prim_);
return geom.GetRadiusAttr().ValueMightBeTimeVarying();
}
WM_reportf(RPT_ERROR,
"Unhandled Gprim type: %s (%s)",
prim_.GetTypeName().GetText(),
prim_.GetPath().GetText());
return false;
}
} // namespace blender::io::usd

View File

@ -0,0 +1,62 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2023 Nvidia. All rights reserved. */
#pragma once
#include "usd.h"
#include "usd_reader_geom.h"
#include "usd_reader_xform.h"
#include <pxr/usd/usdGeom/gprim.h>
struct Mesh;
namespace blender::io::usd {
/*
* Read USDGeom primitive shapes as Blender Meshes. This class uses the same adapter functions
* as the GL viewport to generate geometry for each of the supported types.
*/
class USDShapeReader : public USDGeomReader {
private:
/* Template required to read mesh information out of Shape prims,
* as each prim type has a separate subclass. */
template<typename Adapter>
void read_values(double motionSampleTime,
pxr::VtVec3fArray &positions,
pxr::VtIntArray &face_indices,
pxr::VtIntArray &face_counts) const;
/* Wrapper for the templated method read_values, calling the correct template
* instantiation based on the introspected prim type. */
bool read_mesh_values(double motionSampleTime,
pxr::VtVec3fArray &positions,
pxr::VtIntArray &face_indices,
pxr::VtIntArray &face_counts) const;
/* Read the pxr:UsdGeomMesh values and convert them to a Blender Mesh,
* also returning face_indices and counts for further loop processing. */
Mesh *mesh_from_prim(Mesh *existing_mesh,
double motionSampleTime,
pxr::VtIntArray &face_indices,
pxr::VtIntArray &face_counts) const;
public:
USDShapeReader(const pxr::UsdPrim &prim,
const USDImportParams &import_params,
const ImportSettings &settings);
void create_object(Main *bmain, double /*motionSampleTime*/) override;
void read_object_data(Main *bmain, double motionSampleTime) override;
Mesh *read_mesh(Mesh *existing_mesh,
double motionSampleTime,
int /*read_flag*/,
const char ** /*err_str*/) override;
bool is_time_varying();
virtual bool topology_changed(const Mesh * /*existing_mesh*/, double /*motionSampleTime*/)
{
return false;
};
};
} // namespace blender::io::usd

View File

@ -9,16 +9,22 @@
#include "usd_reader_mesh.h"
#include "usd_reader_nurbs.h"
#include "usd_reader_prim.h"
#include "usd_reader_shape.h"
#include "usd_reader_volume.h"
#include "usd_reader_xform.h"
#include <pxr/pxr.h>
#include <pxr/usd/usd/primRange.h>
#include <pxr/usd/usdGeom/camera.h>
#include <pxr/usd/usdGeom/capsule.h>
#include <pxr/usd/usdGeom/cone.h>
#include <pxr/usd/usdGeom/cube.h>
#include <pxr/usd/usdGeom/curves.h>
#include <pxr/usd/usdGeom/cylinder.h>
#include <pxr/usd/usdGeom/mesh.h>
#include <pxr/usd/usdGeom/nurbsCurves.h>
#include <pxr/usd/usdGeom/scope.h>
#include <pxr/usd/usdGeom/sphere.h>
#include <pxr/usd/usdGeom/xform.h>
#include <pxr/usd/usdShade/material.h>
@ -57,8 +63,18 @@ bool USDStageReader::valid() const
return stage_;
}
bool USDStageReader::is_primitive_prim(const pxr::UsdPrim &prim) const
{
return (prim.IsA<pxr::UsdGeomCapsule>() || prim.IsA<pxr::UsdGeomCylinder>() ||
prim.IsA<pxr::UsdGeomCone>() || prim.IsA<pxr::UsdGeomCube>() ||
prim.IsA<pxr::UsdGeomSphere>());
}
USDPrimReader *USDStageReader::create_reader_if_allowed(const pxr::UsdPrim &prim)
{
if (params_.import_shapes && is_primitive_prim(prim)) {
return new USDShapeReader(prim, params_, settings_);
}
if (params_.import_cameras && prim.IsA<pxr::UsdGeomCamera>()) {
return new USDCameraReader(prim, params_, settings_);
}
@ -91,6 +107,9 @@ USDPrimReader *USDStageReader::create_reader_if_allowed(const pxr::UsdPrim &prim
USDPrimReader *USDStageReader::create_reader(const pxr::UsdPrim &prim)
{
if (is_primitive_prim(prim)) {
return new USDShapeReader(prim, params_, settings_);
}
if (prim.IsA<pxr::UsdGeomCamera>()) {
return new USDCameraReader(prim, params_, settings_);
}

View File

@ -100,6 +100,12 @@ class USDStageReader {
* toggled off.
*/
bool include_by_purpose(const pxr::UsdGeomImageable &imageable) const;
/*
* Returns true if the specified UsdPrim is a UsdGeom primitive,
* procedural shape, such as UsdGeomCube.
*/
bool is_primitive_prim(const pxr::UsdPrim &prim) const;
};
}; // namespace blender::io::usd

View File

@ -66,6 +66,7 @@ struct USDImportParams {
bool import_materials;
bool import_meshes;
bool import_volumes;
bool import_shapes;
char prim_path_mask[1024];
bool import_subdiv;
bool import_instance_proxies;

View File

@ -95,7 +95,8 @@ enum {
/**
* The space is not a regular one opened through the editor menu (for example) but spawned by an
* operator to fulfill some task and then disappear again.
* Can typically be cancelled using Escape, but that is handled on the editor level. */
* Can typically be canceled using Escape, but that is handled on the editor level.
*/
SPACE_FLAG_TYPE_TEMPORARY = (1 << 0),
/**
* Used to mark a space as active but "overlapped" by temporary full-screen spaces. Without this
@ -605,10 +606,13 @@ typedef struct SequencerTimelineOverlay {
typedef enum eSpaceSeq_SequencerTimelineOverlay_Flag {
SEQ_TIMELINE_SHOW_STRIP_OFFSETS = (1 << 1),
SEQ_TIMELINE_SHOW_THUMBNAILS = (1 << 2),
SEQ_TIMELINE_SHOW_STRIP_COLOR_TAG = (1 << 3), /* use Sequence->color_tag */
/** Use #Sequence::color_tag */
SEQ_TIMELINE_SHOW_STRIP_COLOR_TAG = (1 << 3),
SEQ_TIMELINE_SHOW_FCURVES = (1 << 5),
SEQ_TIMELINE_ALL_WAVEFORMS = (1 << 7), /* draw all waveforms */
SEQ_TIMELINE_NO_WAVEFORMS = (1 << 8), /* draw no waveforms */
/** Draw all wave-forms. */
SEQ_TIMELINE_ALL_WAVEFORMS = (1 << 7),
/** Draw no wave-forms. */
SEQ_TIMELINE_NO_WAVEFORMS = (1 << 8),
SEQ_TIMELINE_SHOW_STRIP_NAME = (1 << 14),
SEQ_TIMELINE_SHOW_STRIP_SOURCE = (1 << 15),
SEQ_TIMELINE_SHOW_STRIP_DURATION = (1 << 16),
@ -978,7 +982,7 @@ enum eFileDetails {
FILE_DETAILS_DATETIME = (1 << 1),
};
/* these values need to be hardcoded in structs, dna does not recognize defines */
/* These values need to be hard-coded in structs, DNA does not recognize defines. */
/* also defined in BKE */
#define FILE_MAXDIR 768
#define FILE_MAXFILE 256
@ -1091,13 +1095,14 @@ typedef enum eFileSel_File_Types {
} eFileSel_File_Types;
ENUM_OPERATORS(eFileSel_File_Types, FILE_TYPE_BLENDERLIB);
/** Selection Flags in filesel: struct direntry, unsigned char selflag. */
/** Selection Flags #FileList::selection_state. */
typedef enum eDirEntry_SelectFlag {
/* FILE_SEL_ACTIVE = (1 << 1), */ /* UNUSED */
FILE_SEL_HIGHLIGHTED = (1 << 2),
FILE_SEL_SELECTED = (1 << 3),
FILE_SEL_EDITING = (1 << 4),
} eDirEntry_SelectFlag;
ENUM_OPERATORS(eDirEntry_SelectFlag, FILE_SEL_EDITING);
/* ***** Related to file browser, but never saved in DNA, only here to help with RNA. ***** */
@ -1209,7 +1214,7 @@ typedef struct SpaceImage {
struct Image *image;
struct ImageUser iuser;
/** Histogram waveform and vectorscope. */
/** Histogram waveform and vector-scope. */
struct Scopes scopes;
/** Sample line histogram. */
struct Histogram sample_line_hist;
@ -1588,12 +1593,12 @@ typedef struct SpaceNode {
/* tree type for the current node tree */
char tree_idname[64];
/** Treetype: as same nodetree->type. */
/** Same as #bNodeTree::type (deprecated). */
int treetype DNA_DEPRECATED;
/** Texfrom object, world or brush. */
/** Texture-from object, world or brush (#eSpaceNode_TexFrom). */
short texfrom;
/** Shader from object or world. */
/** Shader from object or world (#eSpaceNode_ShaderFrom). */
short shaderfrom;
/** Grease-pencil data. */
@ -1657,7 +1662,7 @@ typedef struct ConsoleLine {
/* Keep these 3 vars so as to share free, realloc functions. */
/** Allocated length. */
int len_alloc;
/** Real len - strlen(). */
/** Real length: `strlen()`. */
int len;
char *line;
@ -1670,7 +1675,8 @@ typedef struct ConsoleLine {
typedef enum eConsoleLine_Type {
CONSOLE_LINE_OUTPUT = 0,
CONSOLE_LINE_INPUT = 1,
CONSOLE_LINE_INFO = 2, /* autocomp feedback */
/** Auto-completion feedback. */
CONSOLE_LINE_INFO = 2,
CONSOLE_LINE_ERROR = 3,
} eConsoleLine_Type;

View File

@ -275,7 +275,7 @@ static void rna_def_curves_point(BlenderRNA *brna)
prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_CurvePoint_index_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Index", "Index of this points");
RNA_def_property_ui_text(prop, "Index", "Index of this point");
}
/* Defines a read-only vector type since normals can not be modified manually. */

View File

@ -3313,12 +3313,12 @@ static void rna_def_modifier_correctivesmooth(BlenderRNA *brna)
"ORCO",
0,
"Original Coords",
"Use base mesh vertex coords as the rest position"},
"Use base mesh vertex coordinates as the rest position"},
{MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND,
"BIND",
0,
"Bind Coords",
"Use bind vertex coords for rest position"},
"Use bind vertex coordinates for rest position"},
{0, NULL, 0, NULL, NULL},
};
@ -5967,13 +5967,13 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna)
"OVERWRITE",
0,
"Overwrite",
"Replace vertex coords with cached values"},
"Replace vertex coordinates with cached values"},
{MOD_MESHCACHE_DEFORM_INTEGRATE,
"INTEGRATE",
0,
"Integrate",
"Integrate deformation from this modifiers input with the mesh-cache coords (useful for "
"shape keys)"},
"Integrate deformation from this modifier's input with the mesh-cache coordinates "
"(useful for shape keys)"},
{0, NULL, 0, NULL, NULL},
};

View File

@ -544,7 +544,7 @@ static NlaStrip *rna_NlaStrip_new(ID *id,
reports,
RPT_ERROR,
"Unable to add strip (the track does not have any space to accommodate this new strip)");
BKE_nlastrip_free(NULL, strip, true);
BKE_nlastrip_free(strip, true);
return NULL;
}
@ -595,7 +595,7 @@ static void rna_NlaStrip_remove(
return;
}
BKE_nlastrip_free(&track->strips, strip, true);
BKE_nlastrip_remove_and_free(&track->strips, strip, true);
RNA_POINTER_INVALIDATE(strip_ptr);
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL);

View File

@ -162,7 +162,7 @@ static void rna_def_point(BlenderRNA *brna)
prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_Point_index_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Index", "Index of this points");
RNA_def_property_ui_text(prop, "Index", "Index of this point");
}
static void rna_def_pointcloud(BlenderRNA *brna)

View File

@ -75,17 +75,17 @@ set(SRC
nodes/node_geo_extrude_mesh.cc
nodes/node_geo_flip_faces.cc
nodes/node_geo_geometry_to_instance.cc
nodes/node_geo_image.cc
nodes/node_geo_image_info.cc
nodes/node_geo_image_texture.cc
nodes/node_geo_image.cc
nodes/node_geo_input_curve_handles.cc
nodes/node_geo_input_curve_tilt.cc
nodes/node_geo_input_id.cc
nodes/node_geo_input_index.cc
nodes/node_geo_input_instance_rotation.cc
nodes/node_geo_input_instance_scale.cc
nodes/node_geo_input_material_index.cc
nodes/node_geo_input_material.cc
nodes/node_geo_input_material_index.cc
nodes/node_geo_input_mesh_edge_angle.cc
nodes/node_geo_input_mesh_edge_neighbors.cc
nodes/node_geo_input_mesh_edge_vertices.cc
@ -135,17 +135,17 @@ set(SRC
nodes/node_geo_mesh_topology_vertex_of_corner.cc
nodes/node_geo_object_info.cc
nodes/node_geo_offset_point_in_curve.cc
nodes/node_geo_points.cc
nodes/node_geo_points_to_vertices.cc
nodes/node_geo_points_to_volume.cc
nodes/node_geo_points.cc
nodes/node_geo_proximity.cc
nodes/node_geo_raycast.cc
nodes/node_geo_realize_instances.cc
nodes/node_geo_remove_attribute.cc
nodes/node_geo_rotate_instances.cc
nodes/node_geo_sample_index.cc
nodes/node_geo_sample_nearest_surface.cc
nodes/node_geo_sample_nearest.cc
nodes/node_geo_sample_nearest_surface.cc
nodes/node_geo_sample_uv_surface.cc
nodes/node_geo_scale_elements.cc
nodes/node_geo_scale_instances.cc
@ -157,8 +157,8 @@ set(SRC
nodes/node_geo_set_curve_radius.cc
nodes/node_geo_set_curve_tilt.cc
nodes/node_geo_set_id.cc
nodes/node_geo_set_material_index.cc
nodes/node_geo_set_material.cc
nodes/node_geo_set_material_index.cc
nodes/node_geo_set_point_radius.cc
nodes/node_geo_set_position.cc
nodes/node_geo_set_shade_smooth.cc

View File

@ -7,8 +7,8 @@ set(INC
../../gpu
../../makesdna
../../makesrna
../../../../intern/guardedalloc
../../../../intern/clog
../../../../intern/guardedalloc
)
set(INC_SYS