Mesh: Set active attribute values edit mode operator #104426
|
@ -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()
|
||||
|
|
|
@ -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)" \
|
||||
|
|
|
@ -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*)
|
||||
export MY_JOBS_ARG=$i
|
||||
if [ "$MY_JOBS_ARG" = "-j" ]; then
|
||||
add_next=1
|
||||
fi
|
||||
;;
|
||||
--jobs=*)
|
||||
shift # past argument=value
|
||||
export MY_JOBS_ARG=$i
|
||||
;;
|
||||
*)
|
||||
if (( $add_next == 1 )); then
|
||||
export 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" "$@"
|
|
@ -295,7 +295,7 @@ unset(MATERIALX_LIB_FOLDER_EXISTS)
|
|||
if(NOT MSVC_CLANG AND # Available with MSVC 15.7+ but not for CLANG.
|
||||
NOT WITH_WINDOWS_SCCACHE AND # And not when sccache is enabled
|
||||
NOT VS_CLANG_TIDY) # Clang-tidy does not like these options
|
||||
add_compile_options(/experimental:external /external:templates- /external:I "${LIBDIR}" /external:W0)
|
||||
add_compile_options(/experimental:external /external:I "${LIBDIR}" /external:W0)
|
||||
endif()
|
||||
|
||||
# Add each of our libraries to our cmake_prefix_path so find_package() could work
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -686,7 +686,7 @@ ccl_device_inline Spectrum bsdf_albedo(ccl_private const ShaderData *sd,
|
|||
albedo *= ((ccl_private const PrincipledSheenBsdf *)sc)->avg_value;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
|
||||
albedo *= bsdf_principled_hair_albedo(sc);
|
||||
albedo *= bsdf_principled_hair_albedo(sd, sc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -478,10 +478,18 @@ ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(
|
|||
return (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f;
|
||||
}
|
||||
|
||||
ccl_device Spectrum bsdf_principled_hair_albedo(ccl_private const ShaderClosure *sc)
|
||||
ccl_device Spectrum bsdf_principled_hair_albedo(ccl_private const ShaderData *sd,
|
||||
ccl_private const ShaderClosure *sc)
|
||||
{
|
||||
ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc;
|
||||
return exp(-sqrt(bsdf->sigma) * bsdf_principled_hair_albedo_roughness_scale(bsdf->v));
|
||||
|
||||
const float cos_theta_o = cos_from_sin(dot(sd->wi, safe_normalize(sd->dPdu)));
|
||||
const float cos_gamma_o = cos_from_sin(bsdf->extra->geom.w);
|
||||
const float f = fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta);
|
||||
|
||||
const float roughness_scale = bsdf_principled_hair_albedo_roughness_scale(bsdf->v);
|
||||
/* TODO(lukas): Adding the Fresnel term here as a workaround until the proper refactor. */
|
||||
return exp(-sqrt(bsdf->sigma) * roughness_scale) + make_spectrum(f);
|
||||
}
|
||||
|
||||
ccl_device_inline Spectrum
|
||||
|
|
|
@ -281,6 +281,8 @@ inline T *MEM_new(const char *allocation_name, Args &&...args)
|
|||
*/
|
||||
template<typename T> inline void MEM_delete(const T *ptr)
|
||||
{
|
||||
static_assert(!std::is_void_v<T>,
|
||||
"MEM_delete on a void pointer not possible. Cast it to a non-void type?");
|
||||
if (ptr == nullptr) {
|
||||
/* Support #ptr being null, because C++ `delete` supports that as well. */
|
||||
return;
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -6,8 +6,8 @@ from bpy.types import Operator
|
|||
from bpy.app.translations import pgettext_data as data_
|
||||
|
||||
|
||||
def geometry_node_group_empty_new():
|
||||
group = bpy.data.node_groups.new(data_("Geometry Nodes"), 'GeometryNodeTree')
|
||||
def build_default_empty_geometry_node_group(name):
|
||||
group = bpy.data.node_groups.new(name, 'GeometryNodeTree')
|
||||
group.inputs.new('NodeSocketGeometry', data_("Geometry"))
|
||||
group.outputs.new('NodeSocketGeometry', data_("Geometry"))
|
||||
input_node = group.nodes.new('NodeGroupInput')
|
||||
|
@ -20,8 +20,12 @@ def geometry_node_group_empty_new():
|
|||
input_node.location.x = -200 - input_node.width
|
||||
output_node.location.x = 200
|
||||
|
||||
group.links.new(output_node.inputs[0], input_node.outputs[0])
|
||||
return group
|
||||
|
||||
|
||||
def geometry_node_group_empty_new():
|
||||
group = build_default_empty_geometry_node_group(data_("Geometry Nodes"))
|
||||
group.links.new(group.nodes["Group Input"].outputs[0], group.nodes["Group Output"].inputs[0])
|
||||
return group
|
||||
|
||||
|
||||
|
@ -35,6 +39,158 @@ def geometry_modifier_poll(context):
|
|||
return True
|
||||
|
||||
|
||||
def get_context_modifier(context):
|
||||
if context.area.type == 'PROPERTIES':
|
||||
modifier = context.modifier
|
||||
else:
|
||||
modifier = context.object.modifiers.active
|
||||
if modifier is None or modifier.type != 'NODES':
|
||||
return None
|
||||
return modifier
|
||||
|
||||
|
||||
def edit_geometry_nodes_modifier_poll(context):
|
||||
return get_context_modifier(context) is not None
|
||||
|
||||
|
||||
def socket_idname_to_attribute_type(idname):
|
||||
if idname.startswith("NodeSocketInt"):
|
||||
return "INT"
|
||||
elif idname.startswith("NodeSocketColor"):
|
||||
return "FLOAT_COLOR"
|
||||
elif idname.startswith("NodeSocketVector"):
|
||||
return "FLOAT_VECTOR"
|
||||
elif idname.startswith("NodeSocketBool"):
|
||||
return "BOOLEAN"
|
||||
elif idname.startswith("NodeSocketFloat"):
|
||||
return "FLOAT"
|
||||
raise ValueError("Unsupported socket type")
|
||||
return ""
|
||||
|
||||
|
||||
def modifier_attribute_name_get(modifier, identifier):
|
||||
try:
|
||||
return modifier[identifier + "_attribute_name"]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
|
||||
def modifier_input_use_attribute(modifier, identifier):
|
||||
try:
|
||||
return modifier[identifier + "_use_attribute"] != 0
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
|
||||
def get_socket_with_identifier(sockets, identifier):
|
||||
for socket in sockets:
|
||||
if socket.identifier == identifier:
|
||||
return socket
|
||||
return None
|
||||
|
||||
|
||||
def get_enabled_socket_with_name(sockets, name):
|
||||
for socket in sockets:
|
||||
if socket.name == name and socket.enabled:
|
||||
return socket
|
||||
return None
|
||||
|
||||
|
||||
class MoveModifierToNodes(Operator):
|
||||
"""Move inputs and outputs from in the modifier to a new node group"""
|
||||
|
||||
bl_idname = "object.geometry_nodes_move_to_nodes"
|
||||
bl_label = "Move to Nodes"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return edit_geometry_nodes_modifier_poll(context)
|
||||
|
||||
def execute(self, context):
|
||||
modifier = get_context_modifier(context)
|
||||
if not modifier:
|
||||
return {'CANCELLED'}
|
||||
old_group = modifier.node_group
|
||||
if not old_group:
|
||||
return {'CANCELLED'}
|
||||
|
||||
wrapper_name = old_group.name + ".wrapper"
|
||||
group = build_default_empty_geometry_node_group(wrapper_name)
|
||||
group_node = group.nodes.new("GeometryNodeGroup")
|
||||
group_node.node_tree = old_group
|
||||
group_node.update()
|
||||
|
||||
group_input_node = group.nodes["Group Input"]
|
||||
group_output_node = group.nodes["Group Output"]
|
||||
|
||||
# Copy default values for inputs and create named attribute input nodes.
|
||||
input_nodes = []
|
||||
first_geometry_input = None
|
||||
for input_socket in old_group.inputs:
|
||||
identifier = input_socket.identifier
|
||||
group_node_input = get_socket_with_identifier(group_node.inputs, identifier)
|
||||
if modifier_input_use_attribute(modifier, identifier):
|
||||
input_node = group.nodes.new("GeometryNodeInputNamedAttribute")
|
||||
input_nodes.append(input_node)
|
||||
input_node.data_type = socket_idname_to_attribute_type(input_socket.bl_socket_idname)
|
||||
attribute_name = modifier_attribute_name_get(modifier, identifier)
|
||||
input_node.inputs["Name"].default_value = attribute_name
|
||||
output_socket = get_enabled_socket_with_name(input_node.outputs, "Attribute")
|
||||
group.links.new(output_socket, group_node_input)
|
||||
elif hasattr(input_socket, "default_value"):
|
||||
group_node_input.default_value = modifier[identifier]
|
||||
elif input_socket.bl_socket_idname == 'NodeSocketGeometry':
|
||||
if not first_geometry_input:
|
||||
first_geometry_input = group_node_input
|
||||
|
||||
group.links.new(group_input_node.outputs[0], first_geometry_input)
|
||||
|
||||
# Adjust locations of named attribute input nodes and group input node to make some space.
|
||||
if input_nodes:
|
||||
for i, node in enumerate(input_nodes):
|
||||
node.location.x = -175
|
||||
node.location.y = i * -50
|
||||
group_input_node.location.x = -350
|
||||
|
||||
# Connect outputs to store named attribute nodes to replace modifier attribute outputs.
|
||||
store_nodes = []
|
||||
first_geometry_output = None
|
||||
for output_socket in old_group.outputs:
|
||||
identifier = output_socket.identifier
|
||||
group_node_output = get_socket_with_identifier(group_node.outputs, identifier)
|
||||
attribute_name = modifier_attribute_name_get(modifier, identifier)
|
||||
if attribute_name:
|
||||
store_node = group.nodes.new("GeometryNodeStoreNamedAttribute")
|
||||
store_nodes.append(store_node)
|
||||
store_node.data_type = socket_idname_to_attribute_type(output_socket.bl_socket_idname)
|
||||
store_node.domain = output_socket.attribute_domain
|
||||
store_node.inputs["Name"].default_value = attribute_name
|
||||
input_socket = get_enabled_socket_with_name(store_node.inputs, "Value")
|
||||
group.links.new(group_node_output, input_socket)
|
||||
elif output_socket.bl_socket_idname == 'NodeSocketGeometry':
|
||||
if not first_geometry_output:
|
||||
first_geometry_output = group_node_output
|
||||
|
||||
# Adjust locations of store named attribute nodes and move group output.
|
||||
if store_nodes:
|
||||
for i, node in enumerate(store_nodes):
|
||||
node.location.x = (i + 1) * 175
|
||||
node.location.y = 0
|
||||
group_output_node.location.x = (len(store_nodes) + 1) * 175
|
||||
|
||||
group.links.new(first_geometry_output, store_nodes[0].inputs["Geometry"])
|
||||
for i in range(len(store_nodes) - 1):
|
||||
group.links.new(store_nodes[i].outputs["Geometry"], store_nodes[i + 1].inputs["Geometry"])
|
||||
group.links.new(store_nodes[-1].outputs["Geometry"], group_output_node.inputs["Geometry"])
|
||||
else:
|
||||
group.links.new(first_geometry_output, group_output_node.inputs["Geometry"])
|
||||
|
||||
modifier.node_group = group
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class NewGeometryNodesModifier(Operator):
|
||||
"""Create a new modifier with a new geometry node group"""
|
||||
|
||||
|
@ -48,7 +204,6 @@ class NewGeometryNodesModifier(Operator):
|
|||
|
||||
def execute(self, context):
|
||||
modifier = context.object.modifiers.new(data_("GeometryNodes"), "NODES")
|
||||
|
||||
if not modifier:
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
@ -70,11 +225,7 @@ class NewGeometryNodeTreeAssign(Operator):
|
|||
return geometry_modifier_poll(context)
|
||||
|
||||
def execute(self, context):
|
||||
if context.area.type == 'PROPERTIES':
|
||||
modifier = context.modifier
|
||||
else:
|
||||
modifier = context.object.modifiers.active
|
||||
|
||||
modifier = get_context_modifier(context)
|
||||
if not modifier:
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
@ -87,4 +238,5 @@ class NewGeometryNodeTreeAssign(Operator):
|
|||
classes = (
|
||||
NewGeometryNodesModifier,
|
||||
NewGeometryNodeTreeAssign,
|
||||
MoveModifierToNodes,
|
||||
)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -1141,6 +1141,11 @@ def brush_texture_settings(layout, brush, sculpt):
|
|||
# texture_sample_bias
|
||||
layout.prop(brush, "texture_sample_bias", slider=True, text="Sample Bias")
|
||||
|
||||
if brush.sculpt_tool == 'DRAW':
|
||||
col = layout.column()
|
||||
col.active = tex_slot.map_mode == 'AREA_PLANE'
|
||||
col.prop(brush, "use_color_as_displacement", text="Vector Displacement")
|
||||
|
||||
|
||||
def brush_mask_texture_settings(layout, brush):
|
||||
mask_tex_slot = brush.mask_texture_slot
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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):
|
||||
|
|
|
@ -6756,6 +6756,13 @@ class VIEW3D_PT_overlay_sculpt_curves(Panel):
|
|||
row.active = overlay.show_overlays
|
||||
row.prop(overlay, "sculpt_mode_mask_opacity", text="Selection Opacity")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.active = overlay.show_overlays
|
||||
row.prop(overlay, "sculpt_curves_cage", text="")
|
||||
subrow = row.row(align=True)
|
||||
subrow.active = overlay.sculpt_curves_cage
|
||||
subrow.prop(overlay, "sculpt_curves_cage_opacity", text="Cage Opacity")
|
||||
|
||||
|
||||
class VIEW3D_PT_overlay_bones(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
|
|
|
@ -67,6 +67,9 @@ class AssetLibrary {
|
|||
|
||||
std::unique_ptr<AssetCatalogService> catalog_service;
|
||||
|
||||
/** Assets owned by this library should never be linked. */
|
||||
bool never_link = false;
|
||||
|
||||
friend class AssetLibraryService;
|
||||
|
||||
public:
|
||||
|
|
|
@ -22,6 +22,8 @@ const char *AS_asset_representation_name_get(const AssetRepresentation *asset)
|
|||
AssetMetaData *AS_asset_representation_metadata_get(const AssetRepresentation *asset)
|
||||
ATTR_WARN_UNUSED_RESULT;
|
||||
bool AS_asset_representation_is_local_id(const AssetRepresentation *asset) ATTR_WARN_UNUSED_RESULT;
|
||||
bool AS_asset_representation_is_never_link(const AssetRepresentation *asset)
|
||||
ATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup asset_system
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_string_ref.hh"
|
||||
|
||||
namespace blender::asset_system {
|
||||
|
||||
StringRefNull essentials_directory_path();
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@ set(SRC
|
|||
intern/asset_catalog.cc
|
||||
intern/asset_catalog_path.cc
|
||||
intern/asset_catalog_tree.cc
|
||||
intern/asset_essentials_library.cc
|
||||
intern/asset_identifier.cc
|
||||
intern/asset_library.cc
|
||||
intern/asset_library_service.cc
|
||||
|
@ -30,6 +31,7 @@ set(SRC
|
|||
AS_asset_identifier.hh
|
||||
AS_asset_library.hh
|
||||
AS_asset_representation.hh
|
||||
AS_essentials_library.hh
|
||||
intern/asset_library_service.hh
|
||||
intern/asset_storage.hh
|
||||
intern/utils.hh
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup asset_system
|
||||
*/
|
||||
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "BKE_appdir.h"
|
||||
|
||||
#include "AS_essentials_library.hh"
|
||||
|
||||
namespace blender::asset_system {
|
||||
|
||||
StringRefNull essentials_directory_path()
|
||||
{
|
||||
static std::string path = []() {
|
||||
const char *datafiles_path = BKE_appdir_folder_id(BLENDER_DATAFILES, "assets");
|
||||
return datafiles_path;
|
||||
}();
|
||||
return path;
|
||||
}
|
||||
|
||||
} // namespace blender::asset_system
|
|
@ -260,6 +260,12 @@ StringRefNull AssetLibrary::root_path() const
|
|||
Vector<AssetLibraryReference> all_valid_asset_library_refs()
|
||||
{
|
||||
Vector<AssetLibraryReference> result;
|
||||
{
|
||||
AssetLibraryReference library_ref{};
|
||||
library_ref.custom_library_index = -1;
|
||||
library_ref.type = ASSET_LIBRARY_ESSENTIALS;
|
||||
result.append(library_ref);
|
||||
}
|
||||
int i;
|
||||
LISTBASE_FOREACH_INDEX (const bUserAssetLibrary *, asset_library, &U.asset_libraries, i) {
|
||||
if (!BLI_is_dir(asset_library->path)) {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "AS_asset_catalog_tree.hh"
|
||||
#include "AS_asset_library.hh"
|
||||
#include "AS_essentials_library.hh"
|
||||
#include "asset_library_service.hh"
|
||||
#include "utils.hh"
|
||||
|
||||
|
@ -60,6 +61,12 @@ AssetLibrary *AssetLibraryService::get_asset_library(
|
|||
const eAssetLibraryType type = eAssetLibraryType(library_reference.type);
|
||||
|
||||
switch (type) {
|
||||
case ASSET_LIBRARY_ESSENTIALS: {
|
||||
const StringRefNull root_path = essentials_directory_path();
|
||||
AssetLibrary *asset_library = get_asset_library_on_disk(root_path);
|
||||
asset_library->never_link = true;
|
||||
return asset_library;
|
||||
}
|
||||
case ASSET_LIBRARY_LOCAL: {
|
||||
/* For the "Current File" library we get the asset library root path based on main. */
|
||||
std::string root_path = bmain ? AS_asset_library_find_suitable_root_path_from_main(bmain) :
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "DNA_asset_types.h"
|
||||
|
||||
#include "AS_asset_identifier.hh"
|
||||
#include "AS_asset_library.hh"
|
||||
#include "AS_asset_representation.h"
|
||||
#include "AS_asset_representation.hh"
|
||||
|
||||
|
@ -126,4 +127,11 @@ bool AS_asset_representation_is_local_id(const AssetRepresentation *asset_handle
|
|||
return asset->is_local_id();
|
||||
}
|
||||
|
||||
bool AS_asset_representation_is_never_link(const AssetRepresentation *asset_handle)
|
||||
{
|
||||
const asset_system::AssetRepresentation *asset =
|
||||
reinterpret_cast<const asset_system::AssetRepresentation *>(asset_handle);
|
||||
return asset->owner_asset_library().never_link;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -46,6 +46,7 @@ struct GeometryDeformation {
|
|||
* function either retrieves the deformation data from the evaluated object, or falls back to
|
||||
* returning the original data.
|
||||
*/
|
||||
GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig);
|
||||
GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
|
||||
const Object &ob_orig);
|
||||
|
||||
|
|
|
@ -305,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,
|
||||
|
@ -445,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);
|
||||
|
@ -520,7 +520,6 @@ void CustomData_bmesh_free_block_data_exclude_by_type(struct CustomData *data,
|
|||
void *block,
|
||||
eCustomDataMask mask_exclude);
|
||||
|
||||
|
||||
/**
|
||||
* Query info over types.
|
||||
*/
|
||||
|
@ -729,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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -596,7 +596,7 @@ void BKE_crazyspace_api_eval_clear(Object *object)
|
|||
|
||||
namespace blender::bke::crazyspace {
|
||||
|
||||
GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
|
||||
GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval,
|
||||
const Object &ob_orig)
|
||||
{
|
||||
BLI_assert(ob_orig.type == OB_CURVES);
|
||||
|
@ -608,7 +608,6 @@ GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
|
|||
/* Use the undeformed positions by default. */
|
||||
deformation.positions = curves_orig.positions();
|
||||
|
||||
const Object *ob_eval = DEG_get_evaluated_object(&depsgraph, const_cast<Object *>(&ob_orig));
|
||||
if (ob_eval == nullptr) {
|
||||
return deformation;
|
||||
}
|
||||
|
@ -653,4 +652,11 @@ GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
|
|||
return deformation;
|
||||
}
|
||||
|
||||
GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
|
||||
const Object &ob_orig)
|
||||
{
|
||||
const Object *ob_eval = DEG_get_evaluated_object(&depsgraph, const_cast<Object *>(&ob_orig));
|
||||
return get_evaluated_curves_deformation(ob_eval, ob_orig);
|
||||
}
|
||||
|
||||
} // namespace blender::bke::crazyspace
|
||||
|
|
|
@ -5203,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;
|
||||
}
|
||||
|
|
|
@ -92,4 +92,3 @@ TEST(nla_track, BKE_nlatrack_remove_strip)
|
|||
}
|
||||
|
||||
} // namespace blender::bke::tests
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3926,6 +3926,18 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
||||
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
||||
if (sl->spacetype == SPACE_VIEW3D) {
|
||||
View3D *v3d = (View3D *)sl;
|
||||
v3d->overlay.flag |= V3D_OVERLAY_SCULPT_CURVES_CAGE;
|
||||
v3d->overlay.sculpt_curves_cage_opacity = 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep this block, even when empty. */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,7 +186,7 @@ static Vector<MeshToBMeshLayerInfo> mesh_to_bm_copy_info_calc(const CustomData &
|
|||
std::array<int, CD_NUMTYPES> per_type_index;
|
||||
per_type_index.fill(0);
|
||||
for (const int i : IndexRange(bm_data.totlayer)) {
|
||||
CustomDataLayer &bm_layer = bm_data.layers[i];
|
||||
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' ?
|
||||
|
@ -1079,7 +1079,7 @@ static Vector<BMeshToMeshLayerInfo> bm_to_mesh_copy_info_calc(const CustomData &
|
|||
std::array<int, CD_NUMTYPES> per_type_index;
|
||||
per_type_index.fill(0);
|
||||
for (const int i : IndexRange(mesh_data.totlayer)) {
|
||||
CustomDataLayer &mesh_layer = mesh_data.layers[i];
|
||||
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' ?
|
||||
|
@ -1166,7 +1166,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
|
|||
&bm->ldata, CD_PROP_BOOL, BKE_uv_map_pin_name_get(layer_name, sub_layer_name));
|
||||
|
||||
/* 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 doin't exist. */
|
||||
* 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 :
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -702,6 +702,7 @@ set(GLSL_SRC
|
|||
engines/overlay/shaders/overlay_point_varying_color_frag.glsl
|
||||
engines/overlay/shaders/overlay_point_varying_color_varying_outline_aa_frag.glsl
|
||||
engines/overlay/shaders/overlay_pointcloud_only_vert.glsl
|
||||
engines/overlay/shaders/overlay_sculpt_curves_cage_vert.glsl
|
||||
engines/overlay/shaders/overlay_sculpt_curves_selection_frag.glsl
|
||||
engines/overlay/shaders/overlay_sculpt_curves_selection_vert.glsl
|
||||
engines/overlay/shaders/overlay_sculpt_mask_frag.glsl
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -192,4 +192,4 @@ void main()
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,4 +38,4 @@ void main()
|
|||
}
|
||||
tile_start += lod_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,4 +51,4 @@ void main()
|
|||
}
|
||||
tile_start += lod_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,4 +52,4 @@ void main()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,4 +91,4 @@ void main()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,4 +29,4 @@ void main()
|
|||
vec2 pixel = vec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
shadow_tag_usage(vP, P, pixel);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,4 +12,4 @@
|
|||
void main()
|
||||
{
|
||||
shadow_tag_usage(interp.vP, interp.P, gl_FragCoord.xy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,4 +19,4 @@ void main()
|
|||
interp.vP = point_world_to_view(interp.P);
|
||||
|
||||
gl_Position = point_world_to_ndc(interp.P);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,4 +74,4 @@ void main()
|
|||
* thread 0. */
|
||||
}
|
||||
LIGHT_FOREACH_END
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,4 +90,4 @@ void main()
|
|||
tiles_buf[tile_store] = tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "eevee_defines.hh"
|
||||
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -632,6 +632,10 @@ static void OVERLAY_draw_scene(void *vedata)
|
|||
GPU_framebuffer_bind(fbl->overlay_line_fb);
|
||||
}
|
||||
|
||||
if (pd->ctx_mode == CTX_MODE_SCULPT_CURVES) {
|
||||
OVERLAY_sculpt_curves_draw_wires(data);
|
||||
}
|
||||
|
||||
OVERLAY_wireframe_draw(data);
|
||||
OVERLAY_armature_draw(data);
|
||||
OVERLAY_particle_draw(data);
|
||||
|
|
|
@ -120,6 +120,7 @@ typedef struct OVERLAY_PassList {
|
|||
DRWPass *pointcloud_ps;
|
||||
DRWPass *sculpt_mask_ps;
|
||||
DRWPass *sculpt_curves_selection_ps;
|
||||
DRWPass *sculpt_curves_cage_ps;
|
||||
DRWPass *volume_ps;
|
||||
DRWPass *wireframe_ps;
|
||||
DRWPass *wireframe_xray_ps;
|
||||
|
@ -287,6 +288,7 @@ typedef struct OVERLAY_PrivateData {
|
|||
DRWShadingGroup *pointcloud_dots_grp;
|
||||
DRWShadingGroup *sculpt_mask_grp;
|
||||
DRWShadingGroup *sculpt_curves_selection_grp;
|
||||
DRWShadingGroup *sculpt_curves_cage_lines_grp;
|
||||
DRWShadingGroup *viewer_attribute_curve_grp;
|
||||
DRWShadingGroup *viewer_attribute_curves_grp;
|
||||
DRWShadingGroup *viewer_attribute_mesh_grp;
|
||||
|
@ -362,6 +364,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 {
|
||||
|
@ -686,6 +689,7 @@ void OVERLAY_sculpt_draw(OVERLAY_Data *vedata);
|
|||
void OVERLAY_sculpt_curves_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_sculpt_curves_draw(OVERLAY_Data *vedata);
|
||||
void OVERLAY_sculpt_curves_draw_wires(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_viewer_attribute_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_viewer_attribute_cache_populate(OVERLAY_Data *vedata, Object *object);
|
||||
|
@ -775,6 +779,7 @@ GPUShader *OVERLAY_shader_particle_dot(void);
|
|||
GPUShader *OVERLAY_shader_particle_shape(void);
|
||||
GPUShader *OVERLAY_shader_sculpt_mask(void);
|
||||
GPUShader *OVERLAY_shader_sculpt_curves_selection(void);
|
||||
GPUShader *OVERLAY_shader_sculpt_curves_cage(void);
|
||||
GPUShader *OVERLAY_shader_viewer_attribute_curve(void);
|
||||
GPUShader *OVERLAY_shader_viewer_attribute_curves(void);
|
||||
GPUShader *OVERLAY_shader_viewer_attribute_mesh(void);
|
||||
|
|
|
@ -11,23 +11,41 @@
|
|||
#include "overlay_private.hh"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_crazyspace.hh"
|
||||
#include "BKE_curves.hh"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
void OVERLAY_sculpt_curves_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const View3DOverlay &overlay = vedata->stl->pd->overlay;
|
||||
|
||||
const DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->sculpt_curves_selection_ps, state | pd->clipping_state);
|
||||
/* Selection overlay. */
|
||||
{
|
||||
const DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->sculpt_curves_selection_ps, state | pd->clipping_state);
|
||||
|
||||
GPUShader *sh = OVERLAY_shader_sculpt_curves_selection();
|
||||
pd->sculpt_curves_selection_grp = DRW_shgroup_create(sh, psl->sculpt_curves_selection_ps);
|
||||
DRWShadingGroup *grp = pd->sculpt_curves_selection_grp;
|
||||
GPUShader *sh = OVERLAY_shader_sculpt_curves_selection();
|
||||
pd->sculpt_curves_selection_grp = DRW_shgroup_create(sh, psl->sculpt_curves_selection_ps);
|
||||
DRWShadingGroup *grp = pd->sculpt_curves_selection_grp;
|
||||
|
||||
/* Reuse the same mask opacity from sculpt mode, since it wasn't worth it to add a different
|
||||
* property yet. */
|
||||
DRW_shgroup_uniform_float_copy(grp, "selection_opacity", pd->overlay.sculpt_mode_mask_opacity);
|
||||
/* Reuse the same mask opacity from sculpt mode, since it wasn't worth it to add a different
|
||||
* property yet. */
|
||||
DRW_shgroup_uniform_float_copy(grp, "selection_opacity", pd->overlay.sculpt_mode_mask_opacity);
|
||||
}
|
||||
/* Cage overlay. */
|
||||
{
|
||||
const DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL |
|
||||
DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->sculpt_curves_cage_ps, state | pd->clipping_state);
|
||||
|
||||
GPUShader *sh = OVERLAY_shader_sculpt_curves_cage();
|
||||
pd->sculpt_curves_cage_lines_grp = DRW_shgroup_create(sh, psl->sculpt_curves_cage_ps);
|
||||
DRW_shgroup_uniform_float_copy(
|
||||
pd->sculpt_curves_cage_lines_grp, "opacity", overlay.sculpt_curves_cage_opacity);
|
||||
}
|
||||
}
|
||||
|
||||
static bool everything_selected(const Curves &curves_id)
|
||||
|
@ -39,7 +57,7 @@ static bool everything_selected(const Curves &curves_id)
|
|||
return selection.is_single() && selection.get_internal_single();
|
||||
}
|
||||
|
||||
void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *object)
|
||||
static void populate_selection_overlay(OVERLAY_Data *vedata, Object *object)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
Curves *curves = static_cast<Curves *>(object->data);
|
||||
|
@ -68,16 +86,35 @@ void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *object)
|
|||
DRW_shgroup_buffer_texture(grp, "selection_tx", *texture);
|
||||
}
|
||||
|
||||
static void populate_edit_overlay(OVERLAY_Data *vedata, Object *object)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
Curves *curves = static_cast<Curves *>(object->data);
|
||||
|
||||
GPUBatch *geom_lines = DRW_curves_batch_cache_get_edit_lines(curves);
|
||||
DRW_shgroup_call_no_cull(pd->sculpt_curves_cage_lines_grp, geom_lines, object);
|
||||
}
|
||||
|
||||
void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *object)
|
||||
{
|
||||
populate_selection_overlay(vedata, object);
|
||||
const View3DOverlay &overlay = vedata->stl->pd->overlay;
|
||||
if ((overlay.flag & V3D_OVERLAY_SCULPT_CURVES_CAGE) &&
|
||||
overlay.sculpt_curves_cage_opacity > 0.0f) {
|
||||
populate_edit_overlay(vedata, object);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_sculpt_curves_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
OVERLAY_FramebufferList *fbl = vedata->fbl;
|
||||
|
||||
if (DRW_state_is_fbo()) {
|
||||
GPU_framebuffer_bind(pd->painting.in_front ? fbl->overlay_in_front_fb :
|
||||
fbl->overlay_default_fb);
|
||||
}
|
||||
|
||||
DRW_draw_pass(psl->sculpt_curves_selection_ps);
|
||||
}
|
||||
|
||||
void OVERLAY_sculpt_curves_draw_wires(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_draw_pass(psl->sculpt_curves_cage_ps);
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ struct OVERLAY_Shaders {
|
|||
GPUShader *particle_shape;
|
||||
GPUShader *pointcloud_dot;
|
||||
GPUShader *sculpt_mask;
|
||||
GPUShader *sculpt_curves_cage;
|
||||
GPUShader *sculpt_curves_selection;
|
||||
GPUShader *uniform_color;
|
||||
GPUShader *uniform_color_pointcloud;
|
||||
|
@ -856,6 +857,18 @@ GPUShader *OVERLAY_shader_sculpt_curves_selection(void)
|
|||
return sh_data->sculpt_curves_selection;
|
||||
}
|
||||
|
||||
GPUShader *OVERLAY_shader_sculpt_curves_cage(void)
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
|
||||
if (!sh_data->sculpt_curves_cage) {
|
||||
sh_data->sculpt_curves_cage = GPU_shader_create_from_info_name(
|
||||
(draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_sculpt_curves_cage_clipped" :
|
||||
"overlay_sculpt_curves_cage");
|
||||
}
|
||||
return sh_data->sculpt_curves_cage;
|
||||
}
|
||||
|
||||
GPUShader *OVERLAY_shader_viewer_attribute_mesh(void)
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
|
|
|
@ -496,7 +496,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_lattice_wire_clipped)
|
|||
GPU_SHADER_CREATE_INFO(overlay_edit_particle_strand)
|
||||
.do_static_compilation(true)
|
||||
.vertex_in(0, Type::VEC3, "pos")
|
||||
.vertex_in(1, Type::FLOAT, "color")
|
||||
.vertex_in(1, Type::FLOAT, "selection")
|
||||
.sampler(0, ImageType::FLOAT_1D, "weightTex")
|
||||
.push_constant(Type::BOOL, "useWeight")
|
||||
.vertex_out(overlay_edit_smooth_color_iface)
|
||||
|
@ -512,7 +512,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_particle_strand_clipped)
|
|||
GPU_SHADER_CREATE_INFO(overlay_edit_particle_point)
|
||||
.do_static_compilation(true)
|
||||
.vertex_in(0, Type::VEC3, "pos")
|
||||
.vertex_in(1, Type::FLOAT, "color")
|
||||
.vertex_in(1, Type::FLOAT, "selection")
|
||||
.vertex_out(overlay_edit_flat_color_iface)
|
||||
.fragment_out(0, Type::VEC4, "fragColor")
|
||||
.vertex_source("overlay_edit_particle_point_vert.glsl")
|
||||
|
|
|
@ -19,3 +19,24 @@ GPU_SHADER_CREATE_INFO(overlay_sculpt_curves_selection)
|
|||
GPU_SHADER_CREATE_INFO(overlay_sculpt_curves_selection_clipped)
|
||||
.do_static_compilation(true)
|
||||
.additional_info("overlay_sculpt_curves_selection", "drw_clipped");
|
||||
|
||||
GPU_SHADER_INTERFACE_INFO(overlay_sculpt_curves_cage_iface, "")
|
||||
.no_perspective(Type::VEC2, "edgePos")
|
||||
.flat(Type::VEC2, "edgeStart")
|
||||
.smooth(Type::VEC4, "finalColor");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(overlay_sculpt_curves_cage)
|
||||
.do_static_compilation(true)
|
||||
.vertex_in(0, Type::VEC3, "pos")
|
||||
.vertex_in(1, Type::FLOAT, "selection")
|
||||
.vertex_out(overlay_sculpt_curves_cage_iface)
|
||||
.fragment_out(0, Type::VEC4, "fragColor")
|
||||
.fragment_out(1, Type::VEC4, "lineOutput")
|
||||
.push_constant(Type::FLOAT, "opacity")
|
||||
.vertex_source("overlay_sculpt_curves_cage_vert.glsl")
|
||||
.fragment_source("overlay_extra_frag.glsl")
|
||||
.additional_info("draw_modelmat", "draw_view", "draw_globals");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(overlay_sculpt_curves_cage_clipped)
|
||||
.do_static_compilation(true)
|
||||
.additional_info("overlay_sculpt_curves_cage", "drw_clipped");
|
||||
|
|
|
@ -7,7 +7,7 @@ void main()
|
|||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
finalColor = mix(colorWire, colorVertexSelect, color);
|
||||
finalColor = mix(colorWire, colorVertexSelect, selection);
|
||||
|
||||
gl_PointSize = sizeVertex * 2.0;
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@ void main()
|
|||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
if (useWeight) {
|
||||
finalColor = vec4(weight_to_rgb(color), 1.0);
|
||||
finalColor = vec4(weight_to_rgb(selection), 1.0);
|
||||
}
|
||||
else {
|
||||
finalColor = mix(colorWire, colorVertexSelect, color);
|
||||
finalColor = mix(colorWire, colorVertexSelect, selection);
|
||||
}
|
||||
|
||||
view_clipping_distances(world_pos);
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
finalColor = vec4(selection);
|
||||
finalColor.a *= opacity;
|
||||
|
||||
/* Convert to screen position [0..sizeVp]. */
|
||||
edgePos = edgeStart = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
|
||||
}
|
|
@ -684,8 +684,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|||
MeshRenderData *mr = mesh_render_data_create(
|
||||
object, me, is_editmode, is_paint_mode, is_mode_active, obmat, do_final, do_uvedit, ts);
|
||||
mr->use_hide = use_hide;
|
||||
mr->use_subsurf_fdots = mr->me &&
|
||||
mr->me->runtime->subsurf_face_dot_tags.size() == mr->me->totvert;
|
||||
mr->use_subsurf_fdots = mr->me && !mr->me->runtime->subsurf_face_dot_tags.is_empty();
|
||||
mr->use_final_mesh = do_final;
|
||||
|
||||
#ifdef DEBUG_TIME
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "BKE_crazyspace.hh"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_geometry_set.hh"
|
||||
|
||||
|
@ -40,11 +41,9 @@
|
|||
#include "draw_curves_private.hh" /* own include */
|
||||
#include "draw_shader.h"
|
||||
|
||||
using blender::ColorGeometry4f;
|
||||
using blender::float3;
|
||||
using blender::IndexRange;
|
||||
using blender::MutableSpan;
|
||||
using blender::Span;
|
||||
|
||||
namespace blender::draw {
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Curves GPUBatch Cache */
|
||||
|
@ -55,11 +54,11 @@ struct CurvesBatchCache {
|
|||
GPUBatch *edit_points;
|
||||
GPUBatch *edit_lines;
|
||||
|
||||
/* Editmode (original) point positions. */
|
||||
/* Crazy-space point positions for original points. */
|
||||
GPUVertBuf *edit_points_pos;
|
||||
|
||||
/* Editmode data (such as selection). */
|
||||
GPUVertBuf *edit_points_data;
|
||||
/* Selection of original points. */
|
||||
GPUVertBuf *edit_points_selection;
|
||||
|
||||
GPUIndexBuf *edit_lines_ibo;
|
||||
|
||||
|
@ -114,7 +113,7 @@ static void curves_batch_cache_clear_edit_data(CurvesBatchCache *cache)
|
|||
{
|
||||
/* TODO: more granular update tagging. */
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_pos);
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_data);
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_selection);
|
||||
GPU_INDEXBUF_DISCARD_SAFE(cache->edit_lines_ibo);
|
||||
|
||||
GPU_BATCH_DISCARD_SAFE(cache->edit_points);
|
||||
|
@ -150,70 +149,12 @@ static void curves_batch_cache_clear(Curves &curves)
|
|||
curves_batch_cache_clear_edit_data(cache);
|
||||
}
|
||||
|
||||
void DRW_curves_batch_cache_validate(Curves *curves)
|
||||
{
|
||||
if (!curves_batch_cache_valid(*curves)) {
|
||||
curves_batch_cache_clear(*curves);
|
||||
curves_batch_cache_init(*curves);
|
||||
}
|
||||
}
|
||||
|
||||
static CurvesBatchCache &curves_batch_cache_get(Curves &curves)
|
||||
{
|
||||
DRW_curves_batch_cache_validate(&curves);
|
||||
return *static_cast<CurvesBatchCache *>(curves.batch_cache);
|
||||
}
|
||||
|
||||
void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode)
|
||||
{
|
||||
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves->batch_cache);
|
||||
if (cache == nullptr) {
|
||||
return;
|
||||
}
|
||||
switch (mode) {
|
||||
case BKE_CURVES_BATCH_DIRTY_ALL:
|
||||
cache->is_dirty = true;
|
||||
break;
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
void DRW_curves_batch_cache_free(Curves *curves)
|
||||
{
|
||||
curves_batch_cache_clear(*curves);
|
||||
MEM_delete(static_cast<CurvesBatchCache *>(curves->batch_cache));
|
||||
curves->batch_cache = nullptr;
|
||||
}
|
||||
|
||||
void DRW_curves_batch_cache_free_old(Curves *curves, int ctime)
|
||||
{
|
||||
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves->batch_cache);
|
||||
if (cache == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool do_discard = false;
|
||||
|
||||
for (const int i : IndexRange(MAX_HAIR_SUBDIV)) {
|
||||
CurvesEvalFinalCache &final_cache = cache->curves_cache.final[i];
|
||||
|
||||
if (drw_attributes_overlap(&final_cache.attr_used_over_time, &final_cache.attr_used)) {
|
||||
final_cache.last_attr_matching_time = ctime;
|
||||
}
|
||||
|
||||
if (ctime - final_cache.last_attr_matching_time > U.vbotimeout) {
|
||||
do_discard = true;
|
||||
}
|
||||
|
||||
drw_attributes_clear(&final_cache.attr_used_over_time);
|
||||
}
|
||||
|
||||
if (do_discard) {
|
||||
curves_discard_attributes(cache->curves_cache);
|
||||
}
|
||||
}
|
||||
|
||||
static void ensure_seg_pt_count(const Curves &curves, CurvesEvalCache &curves_cache)
|
||||
{
|
||||
if (curves_cache.proc_point_buf != nullptr) {
|
||||
|
@ -231,13 +172,11 @@ struct PositionAndParameter {
|
|||
};
|
||||
|
||||
static void curves_batch_cache_fill_segments_proc_pos(
|
||||
const Curves &curves_id,
|
||||
const bke::CurvesGeometry &curves,
|
||||
MutableSpan<PositionAndParameter> posTime_data,
|
||||
MutableSpan<float> hairLength_data)
|
||||
{
|
||||
using namespace blender;
|
||||
/* TODO: use hair radius layer if available. */
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
const OffsetIndices points_by_curve = curves.points_by_curve();
|
||||
const Span<float3> positions = curves.positions();
|
||||
|
||||
|
@ -270,7 +209,7 @@ static void curves_batch_cache_fill_segments_proc_pos(
|
|||
});
|
||||
}
|
||||
|
||||
static void curves_batch_cache_ensure_procedural_pos(const Curves &curves,
|
||||
static void curves_batch_cache_ensure_procedural_pos(const bke::CurvesGeometry &curves,
|
||||
CurvesEvalCache &cache,
|
||||
GPUMaterial * /*gpu_material*/)
|
||||
{
|
||||
|
@ -301,12 +240,10 @@ static void curves_batch_cache_ensure_procedural_pos(const Curves &curves,
|
|||
}
|
||||
}
|
||||
|
||||
static void curves_batch_cache_ensure_edit_points_pos(const Curves &curves_id,
|
||||
static void curves_batch_cache_ensure_edit_points_pos(const bke::CurvesGeometry &curves,
|
||||
Span<float3> deformed_positions,
|
||||
CurvesBatchCache &cache)
|
||||
{
|
||||
using namespace blender;
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
|
||||
static GPUVertFormat format_pos = {0};
|
||||
static uint pos;
|
||||
if (format_pos.attr_len == 0) {
|
||||
|
@ -315,35 +252,32 @@ static void curves_batch_cache_ensure_edit_points_pos(const Curves &curves_id,
|
|||
|
||||
GPU_vertbuf_init_with_format(cache.edit_points_pos, &format_pos);
|
||||
GPU_vertbuf_data_alloc(cache.edit_points_pos, curves.points_num());
|
||||
|
||||
Span<float3> positions = curves.positions();
|
||||
GPU_vertbuf_attr_fill(cache.edit_points_pos, pos, positions.data());
|
||||
GPU_vertbuf_attr_fill(cache.edit_points_pos, pos, deformed_positions.data());
|
||||
}
|
||||
|
||||
static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id,
|
||||
CurvesBatchCache &cache)
|
||||
static void curves_batch_cache_ensure_edit_points_selection(const bke::CurvesGeometry &curves,
|
||||
const eAttrDomain selection_domain,
|
||||
CurvesBatchCache &cache)
|
||||
{
|
||||
using namespace blender;
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
|
||||
static GPUVertFormat format_data = {0};
|
||||
static uint color;
|
||||
static uint selection_id;
|
||||
if (format_data.attr_len == 0) {
|
||||
color = GPU_vertformat_attr_add(&format_data, "color", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
selection_id = GPU_vertformat_attr_add(
|
||||
&format_data, "selection", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
}
|
||||
|
||||
GPU_vertbuf_init_with_format(cache.edit_points_data, &format_data);
|
||||
GPU_vertbuf_data_alloc(cache.edit_points_data, curves.points_num());
|
||||
GPU_vertbuf_init_with_format(cache.edit_points_selection, &format_data);
|
||||
GPU_vertbuf_data_alloc(cache.edit_points_selection, curves.points_num());
|
||||
|
||||
const OffsetIndices points_by_curve = curves.points_by_curve();
|
||||
|
||||
const VArray<bool> selection = curves.attributes().lookup_or_default<bool>(
|
||||
".selection", eAttrDomain(curves_id.selection_domain), true);
|
||||
switch (curves_id.selection_domain) {
|
||||
".selection", selection_domain, true);
|
||||
switch (selection_domain) {
|
||||
case ATTR_DOMAIN_POINT:
|
||||
for (const int point_i : selection.index_range()) {
|
||||
const float point_selection = selection[point_i] ? 1.0f : 0.0f;
|
||||
GPU_vertbuf_attr_set(cache.edit_points_data, color, point_i, &point_selection);
|
||||
GPU_vertbuf_attr_set(cache.edit_points_selection, selection_id, point_i, &point_selection);
|
||||
}
|
||||
break;
|
||||
case ATTR_DOMAIN_CURVE:
|
||||
|
@ -351,18 +285,19 @@ static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id,
|
|||
const float curve_selection = selection[curve_i] ? 1.0f : 0.0f;
|
||||
const IndexRange points = points_by_curve[curve_i];
|
||||
for (const int point_i : points) {
|
||||
GPU_vertbuf_attr_set(cache.edit_points_data, color, point_i, &curve_selection);
|
||||
GPU_vertbuf_attr_set(
|
||||
cache.edit_points_selection, selection_id, point_i, &curve_selection);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void curves_batch_cache_ensure_edit_lines(const Curves &curves_id, CurvesBatchCache &cache)
|
||||
static void curves_batch_cache_ensure_edit_lines(const bke::CurvesGeometry &curves,
|
||||
CurvesBatchCache &cache)
|
||||
{
|
||||
using namespace blender;
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
|
||||
const int vert_len = curves.points_num();
|
||||
const int curve_len = curves.curves_num();
|
||||
const int index_len = vert_len + curve_len;
|
||||
|
@ -383,14 +318,6 @@ static void curves_batch_cache_ensure_edit_lines(const Curves &curves_id, Curves
|
|||
GPU_indexbuf_build_in_place(&elb, cache.edit_lines_ibo);
|
||||
}
|
||||
|
||||
void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32])
|
||||
{
|
||||
char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
|
||||
GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
|
||||
/* Attributes use auto-name. */
|
||||
BLI_snprintf(r_sampler_name, 32, "a%s", attr_safe_name);
|
||||
}
|
||||
|
||||
static void curves_batch_cache_ensure_procedural_final_attr(CurvesEvalCache &cache,
|
||||
const GPUVertFormat *format,
|
||||
const int subdiv,
|
||||
|
@ -413,7 +340,6 @@ static void curves_batch_ensure_attribute(const Curves &curves,
|
|||
const int subdiv,
|
||||
const int index)
|
||||
{
|
||||
using namespace blender;
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache.proc_attributes_buf[index]);
|
||||
|
||||
char sampler_name[32];
|
||||
|
@ -458,11 +384,10 @@ static void curves_batch_ensure_attribute(const Curves &curves,
|
|||
}
|
||||
}
|
||||
|
||||
static void curves_batch_cache_fill_strands_data(const Curves &curves_id,
|
||||
static void curves_batch_cache_fill_strands_data(const bke::CurvesGeometry &curves,
|
||||
GPUVertBufRaw &data_step,
|
||||
GPUVertBufRaw &seg_step)
|
||||
{
|
||||
const blender::bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
const blender::OffsetIndices points_by_curve = curves.points_by_curve();
|
||||
|
||||
for (const int i : IndexRange(curves.curves_num())) {
|
||||
|
@ -473,7 +398,7 @@ static void curves_batch_cache_fill_strands_data(const Curves &curves_id,
|
|||
}
|
||||
}
|
||||
|
||||
static void curves_batch_cache_ensure_procedural_strand_data(Curves &curves,
|
||||
static void curves_batch_cache_ensure_procedural_strand_data(const bke::CurvesGeometry &curves,
|
||||
CurvesEvalCache &cache)
|
||||
{
|
||||
GPUVertBufRaw data_step, seg_step;
|
||||
|
@ -513,15 +438,12 @@ static void curves_batch_cache_ensure_procedural_final_points(CurvesEvalCache &c
|
|||
cache.final[subdiv].strands_res * cache.strands_len);
|
||||
}
|
||||
|
||||
static void curves_batch_cache_fill_segments_indices(const Curves &curves,
|
||||
static void curves_batch_cache_fill_segments_indices(const bke::CurvesGeometry &curves,
|
||||
const int res,
|
||||
GPUIndexBufBuilder &elb)
|
||||
{
|
||||
const int curves_num = curves.geometry.curve_num;
|
||||
|
||||
uint curr_point = 0;
|
||||
|
||||
for ([[maybe_unused]] const int i : IndexRange(curves_num)) {
|
||||
for ([[maybe_unused]] const int i : IndexRange(curves.curves_num())) {
|
||||
for (int k = 0; k < res; k++) {
|
||||
GPU_indexbuf_add_generic_vert(&elb, curr_point++);
|
||||
}
|
||||
|
@ -529,7 +451,7 @@ static void curves_batch_cache_fill_segments_indices(const Curves &curves,
|
|||
}
|
||||
}
|
||||
|
||||
static void curves_batch_cache_ensure_procedural_indices(Curves &curves,
|
||||
static void curves_batch_cache_ensure_procedural_indices(const bke::CurvesGeometry &curves,
|
||||
CurvesEvalCache &cache,
|
||||
const int thickness_res,
|
||||
const int subdiv)
|
||||
|
@ -624,64 +546,6 @@ static bool curves_ensure_attributes(const Curves &curves,
|
|||
return need_tf_update;
|
||||
}
|
||||
|
||||
bool curves_ensure_procedural_data(Curves *curves,
|
||||
CurvesEvalCache **r_hair_cache,
|
||||
GPUMaterial *gpu_material,
|
||||
const int subdiv,
|
||||
const int thickness_res)
|
||||
{
|
||||
bool need_ft_update = false;
|
||||
|
||||
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
||||
*r_hair_cache = &cache.curves_cache;
|
||||
|
||||
const int steps = 3; /* TODO: don't hard-code? */
|
||||
(*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv);
|
||||
|
||||
/* Refreshed on combing and simulation. */
|
||||
if ((*r_hair_cache)->proc_point_buf == nullptr) {
|
||||
ensure_seg_pt_count(*curves, cache.curves_cache);
|
||||
curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, gpu_material);
|
||||
need_ft_update = true;
|
||||
}
|
||||
|
||||
/* Refreshed if active layer or custom data changes. */
|
||||
if ((*r_hair_cache)->proc_strand_buf == nullptr) {
|
||||
curves_batch_cache_ensure_procedural_strand_data(*curves, cache.curves_cache);
|
||||
}
|
||||
|
||||
/* Refreshed only on subdiv count change. */
|
||||
if ((*r_hair_cache)->final[subdiv].proc_buf == nullptr) {
|
||||
curves_batch_cache_ensure_procedural_final_points(cache.curves_cache, subdiv);
|
||||
need_ft_update = true;
|
||||
}
|
||||
if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == nullptr) {
|
||||
curves_batch_cache_ensure_procedural_indices(
|
||||
*curves, cache.curves_cache, thickness_res, subdiv);
|
||||
}
|
||||
|
||||
need_ft_update |= curves_ensure_attributes(*curves, cache, gpu_material, subdiv);
|
||||
|
||||
return need_ft_update;
|
||||
}
|
||||
|
||||
int DRW_curves_material_count_get(Curves *curves)
|
||||
{
|
||||
return max_ii(1, curves->totcol);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_curves_batch_cache_get_edit_points(Curves *curves)
|
||||
{
|
||||
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
||||
return DRW_batch_request(&cache.edit_points);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_curves_batch_cache_get_edit_lines(Curves *curves)
|
||||
{
|
||||
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
||||
return DRW_batch_request(&cache.edit_lines);
|
||||
}
|
||||
|
||||
static void request_attribute(Curves &curves, const char *name)
|
||||
{
|
||||
CurvesBatchCache &cache = curves_batch_cache_get(curves);
|
||||
|
@ -709,10 +573,145 @@ static void request_attribute(Curves &curves, const char *name)
|
|||
drw_attributes_merge(&final_cache.attr_used, &attributes, cache.render_mutex);
|
||||
}
|
||||
|
||||
} // namespace blender::draw
|
||||
|
||||
void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32])
|
||||
{
|
||||
char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
|
||||
GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
|
||||
/* Attributes use auto-name. */
|
||||
BLI_snprintf(r_sampler_name, 32, "a%s", attr_safe_name);
|
||||
}
|
||||
|
||||
bool curves_ensure_procedural_data(Curves *curves_id,
|
||||
CurvesEvalCache **r_hair_cache,
|
||||
GPUMaterial *gpu_material,
|
||||
const int subdiv,
|
||||
const int thickness_res)
|
||||
{
|
||||
using namespace blender;
|
||||
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
bool need_ft_update = false;
|
||||
|
||||
draw::CurvesBatchCache &cache = draw::curves_batch_cache_get(*curves_id);
|
||||
*r_hair_cache = &cache.curves_cache;
|
||||
|
||||
const int steps = 3; /* TODO: don't hard-code? */
|
||||
(*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv);
|
||||
|
||||
/* Refreshed on combing and simulation. */
|
||||
if ((*r_hair_cache)->proc_point_buf == nullptr) {
|
||||
draw::ensure_seg_pt_count(*curves_id, cache.curves_cache);
|
||||
draw::curves_batch_cache_ensure_procedural_pos(curves, cache.curves_cache, gpu_material);
|
||||
need_ft_update = true;
|
||||
}
|
||||
|
||||
/* Refreshed if active layer or custom data changes. */
|
||||
if ((*r_hair_cache)->proc_strand_buf == nullptr) {
|
||||
draw::curves_batch_cache_ensure_procedural_strand_data(curves, cache.curves_cache);
|
||||
}
|
||||
|
||||
/* Refreshed only on subdiv count change. */
|
||||
if ((*r_hair_cache)->final[subdiv].proc_buf == nullptr) {
|
||||
draw::curves_batch_cache_ensure_procedural_final_points(cache.curves_cache, subdiv);
|
||||
need_ft_update = true;
|
||||
}
|
||||
if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == nullptr) {
|
||||
draw::curves_batch_cache_ensure_procedural_indices(
|
||||
curves, cache.curves_cache, thickness_res, subdiv);
|
||||
}
|
||||
|
||||
need_ft_update |= draw::curves_ensure_attributes(*curves_id, cache, gpu_material, subdiv);
|
||||
|
||||
return need_ft_update;
|
||||
}
|
||||
|
||||
void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode)
|
||||
{
|
||||
using namespace blender::draw;
|
||||
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves->batch_cache);
|
||||
if (cache == nullptr) {
|
||||
return;
|
||||
}
|
||||
switch (mode) {
|
||||
case BKE_CURVES_BATCH_DIRTY_ALL:
|
||||
cache->is_dirty = true;
|
||||
break;
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
void DRW_curves_batch_cache_validate(Curves *curves)
|
||||
{
|
||||
using namespace blender::draw;
|
||||
if (!curves_batch_cache_valid(*curves)) {
|
||||
curves_batch_cache_clear(*curves);
|
||||
curves_batch_cache_init(*curves);
|
||||
}
|
||||
}
|
||||
|
||||
void DRW_curves_batch_cache_free(Curves *curves)
|
||||
{
|
||||
using namespace blender::draw;
|
||||
curves_batch_cache_clear(*curves);
|
||||
MEM_delete(static_cast<CurvesBatchCache *>(curves->batch_cache));
|
||||
curves->batch_cache = nullptr;
|
||||
}
|
||||
|
||||
void DRW_curves_batch_cache_free_old(Curves *curves, int ctime)
|
||||
{
|
||||
using namespace blender::draw;
|
||||
CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves->batch_cache);
|
||||
if (cache == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool do_discard = false;
|
||||
|
||||
for (const int i : IndexRange(MAX_HAIR_SUBDIV)) {
|
||||
CurvesEvalFinalCache &final_cache = cache->curves_cache.final[i];
|
||||
|
||||
if (drw_attributes_overlap(&final_cache.attr_used_over_time, &final_cache.attr_used)) {
|
||||
final_cache.last_attr_matching_time = ctime;
|
||||
}
|
||||
|
||||
if (ctime - final_cache.last_attr_matching_time > U.vbotimeout) {
|
||||
do_discard = true;
|
||||
}
|
||||
|
||||
drw_attributes_clear(&final_cache.attr_used_over_time);
|
||||
}
|
||||
|
||||
if (do_discard) {
|
||||
curves_discard_attributes(cache->curves_cache);
|
||||
}
|
||||
}
|
||||
|
||||
int DRW_curves_material_count_get(Curves *curves)
|
||||
{
|
||||
return max_ii(1, curves->totcol);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_curves_batch_cache_get_edit_points(Curves *curves)
|
||||
{
|
||||
using namespace blender::draw;
|
||||
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
||||
return DRW_batch_request(&cache.edit_points);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_curves_batch_cache_get_edit_lines(Curves *curves)
|
||||
{
|
||||
using namespace blender::draw;
|
||||
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
||||
return DRW_batch_request(&cache.edit_lines);
|
||||
}
|
||||
|
||||
GPUVertBuf **DRW_curves_texture_for_evaluated_attribute(Curves *curves,
|
||||
const char *name,
|
||||
bool *r_is_point_domain)
|
||||
{
|
||||
using namespace blender::draw;
|
||||
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const Scene *scene = draw_ctx->scene;
|
||||
|
@ -747,28 +746,37 @@ GPUVertBuf **DRW_curves_texture_for_evaluated_attribute(Curves *curves,
|
|||
|
||||
void DRW_curves_batch_cache_create_requested(Object *ob)
|
||||
{
|
||||
Curves *curves = static_cast<Curves *>(ob->data);
|
||||
Object *orig = DEG_get_original_object(ob);
|
||||
Curves *curves_orig = static_cast<Curves *>(orig->data);
|
||||
using namespace blender;
|
||||
Curves *curves_id = static_cast<Curves *>(ob->data);
|
||||
Object *ob_orig = DEG_get_original_object(ob);
|
||||
if (ob_orig == nullptr) {
|
||||
return;
|
||||
}
|
||||
Curves *curves_orig_id = static_cast<Curves *>(ob_orig->data);
|
||||
|
||||
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
|
||||
draw::CurvesBatchCache &cache = draw::curves_batch_cache_get(*curves_id);
|
||||
bke::CurvesGeometry &curves_orig = curves_orig_id->geometry.wrap();
|
||||
|
||||
const bke::crazyspace::GeometryDeformation deformation =
|
||||
bke::crazyspace::get_evaluated_curves_deformation(ob, *ob_orig);
|
||||
|
||||
if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) {
|
||||
DRW_vbo_request(cache.edit_points, &cache.edit_points_pos);
|
||||
DRW_vbo_request(cache.edit_points, &cache.edit_points_data);
|
||||
DRW_vbo_request(cache.edit_points, &cache.edit_points_selection);
|
||||
}
|
||||
if (DRW_batch_requested(cache.edit_lines, GPU_PRIM_LINE_STRIP)) {
|
||||
DRW_ibo_request(cache.edit_lines, &cache.edit_lines_ibo);
|
||||
DRW_vbo_request(cache.edit_lines, &cache.edit_points_pos);
|
||||
DRW_vbo_request(cache.edit_lines, &cache.edit_points_data);
|
||||
DRW_vbo_request(cache.edit_lines, &cache.edit_points_selection);
|
||||
}
|
||||
if (DRW_vbo_requested(cache.edit_points_pos)) {
|
||||
curves_batch_cache_ensure_edit_points_pos(*curves_orig, cache);
|
||||
curves_batch_cache_ensure_edit_points_pos(curves_orig, deformation.positions, cache);
|
||||
}
|
||||
if (DRW_vbo_requested(cache.edit_points_data)) {
|
||||
curves_batch_cache_ensure_edit_points_data(*curves_orig, cache);
|
||||
if (DRW_vbo_requested(cache.edit_points_selection)) {
|
||||
curves_batch_cache_ensure_edit_points_selection(
|
||||
curves_orig, eAttrDomain(curves_id->selection_domain), cache);
|
||||
}
|
||||
if (DRW_ibo_requested(cache.edit_lines_ibo)) {
|
||||
curves_batch_cache_ensure_edit_lines(*curves_orig, cache);
|
||||
curves_batch_cache_ensure_edit_lines(curves_orig, cache);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,21 +89,21 @@ typedef struct HairAttributeID {
|
|||
|
||||
typedef struct EditStrandData {
|
||||
float pos[3];
|
||||
float color;
|
||||
float selection;
|
||||
} EditStrandData;
|
||||
|
||||
static GPUVertFormat *edit_points_vert_format_get(uint *r_pos_id, uint *r_color_id)
|
||||
static GPUVertFormat *edit_points_vert_format_get(uint *r_pos_id, uint *r_selection_id)
|
||||
{
|
||||
static GPUVertFormat edit_point_format = {0};
|
||||
static uint pos_id, color_id;
|
||||
static uint pos_id, selection_id;
|
||||
if (edit_point_format.attr_len == 0) {
|
||||
/* Keep in sync with EditStrandData */
|
||||
pos_id = GPU_vertformat_attr_add(&edit_point_format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
color_id = GPU_vertformat_attr_add(
|
||||
&edit_point_format, "color", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
selection_id = GPU_vertformat_attr_add(
|
||||
&edit_point_format, "selection", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
}
|
||||
*r_pos_id = pos_id;
|
||||
*r_color_id = color_id;
|
||||
*r_selection_id = selection_id;
|
||||
return &edit_point_format;
|
||||
}
|
||||
|
||||
|
@ -697,11 +697,11 @@ static int particle_batch_cache_fill_segments_edit(
|
|||
if (particle) {
|
||||
float weight = particle_key_weight(particle, i, strand_t);
|
||||
/* NaN or unclamped become 1.0f */
|
||||
seg_data->color = (weight < 1.0f) ? weight : 1.0f;
|
||||
seg_data->selection = (weight < 1.0f) ? weight : 1.0f;
|
||||
}
|
||||
else {
|
||||
/* Computed in psys_cache_edit_paths_iter(). */
|
||||
seg_data->color = path[j].col[0];
|
||||
seg_data->selection = path[j].col[0];
|
||||
}
|
||||
GPU_indexbuf_add_generic_vert(elb, curr_point);
|
||||
curr_point++;
|
||||
|
@ -1530,8 +1530,8 @@ static void particle_batch_cache_ensure_edit_pos_and_seg(PTCacheEdit *edit,
|
|||
|
||||
GPUVertBufRaw data_step;
|
||||
GPUIndexBufBuilder elb;
|
||||
uint pos_id, color_id;
|
||||
GPUVertFormat *edit_point_format = edit_points_vert_format_get(&pos_id, &color_id);
|
||||
uint pos_id, selection_id;
|
||||
GPUVertFormat *edit_point_format = edit_points_vert_format_get(&pos_id, &selection_id);
|
||||
|
||||
hair_cache->pos = GPU_vertbuf_create_with_format(edit_point_format);
|
||||
GPU_vertbuf_data_alloc(hair_cache->pos, hair_cache->point_len);
|
||||
|
@ -1594,8 +1594,8 @@ static void particle_batch_cache_ensure_edit_inner_pos(PTCacheEdit *edit,
|
|||
return;
|
||||
}
|
||||
|
||||
uint pos_id, color_id;
|
||||
GPUVertFormat *edit_point_format = edit_points_vert_format_get(&pos_id, &color_id);
|
||||
uint pos_id, selection_id;
|
||||
GPUVertFormat *edit_point_format = edit_points_vert_format_get(&pos_id, &selection_id);
|
||||
|
||||
cache->edit_inner_pos = GPU_vertbuf_create_with_format(edit_point_format);
|
||||
GPU_vertbuf_data_alloc(cache->edit_inner_pos, cache->edit_inner_point_len);
|
||||
|
@ -1608,9 +1608,9 @@ static void particle_batch_cache_ensure_edit_inner_pos(PTCacheEdit *edit,
|
|||
}
|
||||
for (int key_index = 0; key_index < point->totkey - 1; key_index++) {
|
||||
PTCacheEditKey *key = &point->keys[key_index];
|
||||
float color = (key->flag & PEK_SELECT) ? 1.0f : 0.0f;
|
||||
float selection = (key->flag & PEK_SELECT) ? 1.0f : 0.0f;
|
||||
GPU_vertbuf_attr_set(cache->edit_inner_pos, pos_id, global_key_index, key->world_co);
|
||||
GPU_vertbuf_attr_set(cache->edit_inner_pos, color_id, global_key_index, &color);
|
||||
GPU_vertbuf_attr_set(cache->edit_inner_pos, selection_id, global_key_index, &selection);
|
||||
global_key_index++;
|
||||
}
|
||||
}
|
||||
|
@ -1652,8 +1652,8 @@ static void particle_batch_cache_ensure_edit_tip_pos(PTCacheEdit *edit, Particle
|
|||
return;
|
||||
}
|
||||
|
||||
uint pos_id, color_id;
|
||||
GPUVertFormat *edit_point_format = edit_points_vert_format_get(&pos_id, &color_id);
|
||||
uint pos_id, selection_id;
|
||||
GPUVertFormat *edit_point_format = edit_points_vert_format_get(&pos_id, &selection_id);
|
||||
|
||||
cache->edit_tip_pos = GPU_vertbuf_create_with_format(edit_point_format);
|
||||
GPU_vertbuf_data_alloc(cache->edit_tip_pos, cache->edit_tip_point_len);
|
||||
|
@ -1665,10 +1665,10 @@ static void particle_batch_cache_ensure_edit_tip_pos(PTCacheEdit *edit, Particle
|
|||
continue;
|
||||
}
|
||||
PTCacheEditKey *key = &point->keys[point->totkey - 1];
|
||||
float color = (key->flag & PEK_SELECT) ? 1.0f : 0.0f;
|
||||
float selection = (key->flag & PEK_SELECT) ? 1.0f : 0.0f;
|
||||
|
||||
GPU_vertbuf_attr_set(cache->edit_tip_pos, pos_id, global_point_index, key->world_co);
|
||||
GPU_vertbuf_attr_set(cache->edit_tip_pos, color_id, global_point_index, &color);
|
||||
GPU_vertbuf_attr_set(cache->edit_tip_pos, selection_id, global_point_index, &selection);
|
||||
global_point_index++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ AssetLibraryReference ED_asset_library_reference_from_enum_value(int value)
|
|||
if (value < ASSET_LIBRARY_CUSTOM) {
|
||||
library.type = value;
|
||||
library.custom_library_index = -1;
|
||||
BLI_assert(ELEM(value, ASSET_LIBRARY_ALL, ASSET_LIBRARY_LOCAL));
|
||||
BLI_assert(ELEM(value, ASSET_LIBRARY_ALL, ASSET_LIBRARY_LOCAL, ASSET_LIBRARY_ESSENTIALS));
|
||||
return library;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ AssetLibraryReference ED_asset_library_reference_from_enum_value(int value)
|
|||
/* Note that there is no check if the path exists here. If an invalid library path is used, the
|
||||
* Asset Browser can give a nice hint on what's wrong. */
|
||||
if (!user_library) {
|
||||
library.type = ASSET_LIBRARY_LOCAL;
|
||||
library.type = ASSET_LIBRARY_ALL;
|
||||
library.custom_library_index = -1;
|
||||
}
|
||||
else {
|
||||
|
@ -87,6 +87,11 @@ const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf(const bool
|
|||
ICON_CURRENT_FILE,
|
||||
"Current File",
|
||||
"Show the assets currently available in this Blender session"},
|
||||
{ASSET_LIBRARY_ESSENTIALS,
|
||||
"ESSENTIALS",
|
||||
ICON_NONE,
|
||||
"Essentials",
|
||||
"Show the basic building blocks and utilities coming with Blender"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
|
|
|
@ -372,6 +372,7 @@ std::optional<eFileSelectType> AssetListStorage::asset_library_reference_to_file
|
|||
switch (eAssetLibraryType(library_reference.type)) {
|
||||
case ASSET_LIBRARY_ALL:
|
||||
return FILE_ASSET_LIBRARY_ALL;
|
||||
case ASSET_LIBRARY_ESSENTIALS:
|
||||
case ASSET_LIBRARY_CUSTOM:
|
||||
return FILE_ASSET_LIBRARY;
|
||||
case ASSET_LIBRARY_LOCAL:
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
/* The same as in `draw_cache.c` */
|
||||
#define CIRCLE_RESOL 32
|
||||
|
||||
static int gizmo_cage2d_transform_flag_get(const wmGizmo *gz);
|
||||
|
||||
static bool gizmo_calc_rect_view_scale(const wmGizmo *gz, const float dims[2], float scale[2])
|
||||
{
|
||||
float matrix_final_no_offset[4][4];
|
||||
|
@ -616,7 +618,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
|
|||
RNA_float_get_array(gz->ptr, "dimensions", dims);
|
||||
float matrix_final[4][4];
|
||||
|
||||
const int transform_flag = RNA_enum_get(gz->ptr, "transform");
|
||||
const int transform_flag = gizmo_cage2d_transform_flag_get(gz);
|
||||
const int draw_style = RNA_enum_get(gz->ptr, "draw_style");
|
||||
const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
|
||||
|
||||
|
@ -831,7 +833,7 @@ static int gizmo_cage2d_test_select(bContext *C, wmGizmo *gz, const int mval[2])
|
|||
/* Expand for hots-pot. */
|
||||
const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2};
|
||||
|
||||
const int transform_flag = RNA_enum_get(gz->ptr, "transform");
|
||||
const int transform_flag = gizmo_cage2d_transform_flag_get(gz);
|
||||
const int draw_options = RNA_enum_get(gz->ptr, "draw_options");
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) {
|
||||
|
@ -934,8 +936,21 @@ typedef struct RectTransformInteraction {
|
|||
float orig_matrix_offset[4][4];
|
||||
float orig_matrix_final_no_offset[4][4];
|
||||
Dial *dial;
|
||||
bool use_temp_uniform;
|
||||
} RectTransformInteraction;
|
||||
|
||||
static int gizmo_cage2d_transform_flag_get(const wmGizmo *gz)
|
||||
{
|
||||
RectTransformInteraction *data = gz->interaction_data;
|
||||
int transform_flag = RNA_enum_get(gz->ptr, "transform");
|
||||
if (data) {
|
||||
if (data->use_temp_uniform) {
|
||||
transform_flag |= ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM;
|
||||
}
|
||||
}
|
||||
return transform_flag;
|
||||
}
|
||||
|
||||
static void gizmo_cage2d_setup(wmGizmo *gz)
|
||||
{
|
||||
gz->flag |= WM_GIZMO_DRAW_MODAL | WM_GIZMO_DRAW_NO_SCALE;
|
||||
|
@ -1020,9 +1035,6 @@ static int gizmo_cage2d_modal(bContext *C,
|
|||
const wmEvent *event,
|
||||
eWM_GizmoFlagTweak UNUSED(tweak_flag))
|
||||
{
|
||||
if (event->type != MOUSEMOVE) {
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
/* For transform logic to be manageable we operate in -0.5..0.5 2D space,
|
||||
* no matter the size of the rectangle, mouse coords are scaled to unit space.
|
||||
* The mouse coords have been projected into the matrix
|
||||
|
@ -1032,6 +1044,25 @@ static int gizmo_cage2d_modal(bContext *C,
|
|||
* - Matrix translation is also multiplied by 'dims'.
|
||||
*/
|
||||
RectTransformInteraction *data = gz->interaction_data;
|
||||
int transform_flag = RNA_enum_get(gz->ptr, "transform");
|
||||
if ((transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM) == 0) {
|
||||
/* WARNING: Checking the events modifier only makes sense as long as `tweak_flag`
|
||||
* remains unused (this controls #WM_GIZMO_TWEAK_PRECISE by default). */
|
||||
const bool use_temp_uniform = (event->modifier & KM_SHIFT) != 0;
|
||||
const bool changed = data->use_temp_uniform != use_temp_uniform;
|
||||
data->use_temp_uniform = data->use_temp_uniform;
|
||||
if (use_temp_uniform) {
|
||||
transform_flag |= ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
/* Always refresh. */
|
||||
}
|
||||
else if (event->type != MOUSEMOVE) {
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
}
|
||||
|
||||
float point_local[2];
|
||||
|
||||
float dims[2];
|
||||
|
@ -1050,7 +1081,6 @@ static int gizmo_cage2d_modal(bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
const int transform_flag = RNA_enum_get(gz->ptr, "transform");
|
||||
wmGizmoProperty *gz_prop;
|
||||
|
||||
gz_prop = WM_gizmo_target_property_find(gz, "matrix");
|
||||
|
|
|
@ -86,8 +86,7 @@ struct Dial3dParams {
|
|||
float arc_inner_factor;
|
||||
float *clip_plane;
|
||||
};
|
||||
static void dial_3d_draw_util(const float matrix_basis[4][4],
|
||||
const float matrix_final[4][4],
|
||||
static void dial_3d_draw_util(const float matrix_final[4][4],
|
||||
const float line_width,
|
||||
const float color[4],
|
||||
const bool select,
|
||||
|
@ -96,7 +95,7 @@ static void dial_3d_draw_util(const float matrix_basis[4][4],
|
|||
static void dial_geom_draw(const float color[4],
|
||||
const float line_width,
|
||||
const bool select,
|
||||
const float axis_modal_mat[4][4],
|
||||
const float clip_plane_mat[4][4],
|
||||
const float clip_plane[4],
|
||||
const float arc_partial_angle,
|
||||
const float arc_inner_factor,
|
||||
|
@ -118,7 +117,7 @@ static void dial_geom_draw(const float color[4],
|
|||
immBindBuiltinProgram(filled ? GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR :
|
||||
GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR);
|
||||
immUniform4fv("ClipPlane", clip_plane);
|
||||
immUniformMatrix4fv("ModelMatrix", axis_modal_mat);
|
||||
immUniformMatrix4fv("ModelMatrix", clip_plane_mat);
|
||||
}
|
||||
else {
|
||||
immBindBuiltinProgram(filled ? GPU_SHADER_3D_UNIFORM_COLOR :
|
||||
|
@ -432,8 +431,7 @@ static void dial_draw_intern(
|
|||
}
|
||||
}
|
||||
|
||||
dial_3d_draw_util(gz->matrix_basis,
|
||||
matrix_final,
|
||||
dial_3d_draw_util(matrix_final,
|
||||
gz->line_width,
|
||||
color,
|
||||
select,
|
||||
|
@ -613,8 +611,7 @@ static int gizmo_dial_invoke(bContext *UNUSED(C), wmGizmo *gz, const wmEvent *ev
|
|||
/** \name Dial Gizmo API
|
||||
* \{ */
|
||||
|
||||
static void dial_3d_draw_util(const float matrix_basis[4][4],
|
||||
const float matrix_final[4][4],
|
||||
static void dial_3d_draw_util(const float matrix_final[4][4],
|
||||
const float line_width,
|
||||
const float color[4],
|
||||
const bool select,
|
||||
|
@ -650,7 +647,7 @@ static void dial_3d_draw_util(const float matrix_basis[4][4],
|
|||
dial_geom_draw(color,
|
||||
line_width,
|
||||
select,
|
||||
matrix_basis,
|
||||
matrix_final,
|
||||
params->clip_plane,
|
||||
params->arc_partial_angle,
|
||||
params->arc_inner_factor,
|
||||
|
|
|
@ -279,7 +279,7 @@ static void annotation_draw_stroke_point(const bGPDspoint *points,
|
|||
immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
|
||||
}
|
||||
else {
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
|
||||
|
||||
/* get 2D coordinates of point */
|
||||
float co[3] = {0.0f};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
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);
|
||||
|
|
|
@ -993,23 +993,25 @@ static void draw_mouse_position(tGPDfill *tgpf)
|
|||
if (tgpf->gps_mouse == NULL) {
|
||||
return;
|
||||
}
|
||||
uchar mouse_color[4] = {0, 0, 255, 255};
|
||||
|
||||
bGPDspoint *pt = &tgpf->gps_mouse->points[0];
|
||||
float point_size = (tgpf->zoom == 1.0f) ? 4.0f * tgpf->fill_factor :
|
||||
(0.5f * tgpf->zoom) + tgpf->fill_factor;
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
||||
|
||||
/* Draw mouse click position in Blue. */
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
|
||||
immUniform1f("size", point_size * M_SQRT2);
|
||||
GPU_program_point_size(true);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
|
||||
immBegin(GPU_PRIM_POINTS, 1);
|
||||
immAttr4ubv(col, mouse_color);
|
||||
immAttr1f(size, point_size * M_SQRT2);
|
||||
immAttr4f(color, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
immVertex3fv(pos, &pt->x);
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
GPU_program_point_size(false);
|
||||
}
|
||||
|
||||
/* Helper: Check if must skip the layer */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -966,7 +966,7 @@ static void min_distance_edit_draw(bContext *C, int /*x*/, int /*y*/, void *cust
|
|||
const uint pos3d = GPU_vertformat_attr_add(format3d, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
const uint col3d = GPU_vertformat_attr_add(format3d, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
|
||||
immUniform1f("size", 4.0f);
|
||||
immBegin(GPU_PRIM_POINTS, points_wo.size());
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "WM_api.h"
|
||||
#include "wm_cursors.h"
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "ED_image.h"
|
||||
|
@ -200,10 +201,18 @@ static void load_tex_task_cb_ex(void *__restrict userdata,
|
|||
y = len * sinf(angle);
|
||||
}
|
||||
|
||||
if (col) {
|
||||
float rgba[4];
|
||||
float avg;
|
||||
float rgba[4];
|
||||
paint_get_tex_pixel(mtex, x, y, pool, thread_id, &avg, rgba);
|
||||
|
||||
paint_get_tex_pixel_col(mtex, x, y, rgba, pool, thread_id, convert_to_linear, colorspace);
|
||||
if (col) {
|
||||
if (convert_to_linear) {
|
||||
IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, colorspace);
|
||||
}
|
||||
|
||||
linearrgb_to_srgb_v3_v3(rgba, rgba);
|
||||
|
||||
clamp_v4(rgba, 0.0f, 1.0f);
|
||||
|
||||
buffer[index * 4] = rgba[0] * 255;
|
||||
buffer[index * 4 + 1] = rgba[1] * 255;
|
||||
|
@ -211,8 +220,6 @@ static void load_tex_task_cb_ex(void *__restrict userdata,
|
|||
buffer[index * 4 + 3] = rgba[3] * 255;
|
||||
}
|
||||
else {
|
||||
float avg = paint_get_tex_pixel(mtex, x, y, pool, thread_id);
|
||||
|
||||
avg += br->texture_sample_bias;
|
||||
|
||||
/* Clamp to avoid precision overflow. */
|
||||
|
|
|
@ -352,16 +352,17 @@ void paint_calc_redraw_planes(float planes[4][4],
|
|||
float paint_calc_object_space_radius(struct ViewContext *vc,
|
||||
const float center[3],
|
||||
float pixel_radius);
|
||||
float paint_get_tex_pixel(
|
||||
const struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread);
|
||||
void paint_get_tex_pixel_col(const struct MTex *mtex,
|
||||
float u,
|
||||
float v,
|
||||
float rgba[4],
|
||||
struct ImagePool *pool,
|
||||
int thread,
|
||||
bool convert,
|
||||
struct ColorSpace *colorspace);
|
||||
|
||||
/**
|
||||
* Returns true when a color was sampled and false when a value was sampled.
|
||||
*/
|
||||
bool paint_get_tex_pixel(const struct MTex *mtex,
|
||||
float u,
|
||||
float v,
|
||||
struct ImagePool *pool,
|
||||
int thread,
|
||||
float *r_intensity,
|
||||
float r_rgba[4]);
|
||||
|
||||
/**
|
||||
* Used for both 3D view and image window.
|
||||
|
|
|
@ -146,45 +146,29 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3], flo
|
|||
return len_v3(delta) / scale;
|
||||
}
|
||||
|
||||
float paint_get_tex_pixel(const MTex *mtex, float u, float v, struct ImagePool *pool, int thread)
|
||||
{
|
||||
float intensity;
|
||||
float rgba_dummy[4];
|
||||
const float co[3] = {u, v, 0.0f};
|
||||
|
||||
RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba_dummy);
|
||||
|
||||
return intensity;
|
||||
}
|
||||
|
||||
void paint_get_tex_pixel_col(const MTex *mtex,
|
||||
float u,
|
||||
float v,
|
||||
float rgba[4],
|
||||
struct ImagePool *pool,
|
||||
int thread,
|
||||
bool convert_to_linear,
|
||||
struct ColorSpace *colorspace)
|
||||
bool paint_get_tex_pixel(const MTex *mtex,
|
||||
float u,
|
||||
float v,
|
||||
struct ImagePool *pool,
|
||||
int thread,
|
||||
/* Return arguments. */
|
||||
float *r_intensity,
|
||||
float r_rgba[4])
|
||||
{
|
||||
const float co[3] = {u, v, 0.0f};
|
||||
float intensity;
|
||||
const bool has_rgb = RE_texture_evaluate(
|
||||
mtex, co, thread, pool, false, false, &intensity, r_rgba);
|
||||
*r_intensity = intensity;
|
||||
|
||||
const bool hasrgb = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba);
|
||||
|
||||
if (!hasrgb) {
|
||||
rgba[0] = intensity;
|
||||
rgba[1] = intensity;
|
||||
rgba[2] = intensity;
|
||||
rgba[3] = 1.0f;
|
||||
if (!has_rgb) {
|
||||
r_rgba[0] = intensity;
|
||||
r_rgba[1] = intensity;
|
||||
r_rgba[2] = intensity;
|
||||
r_rgba[3] = 1.0f;
|
||||
}
|
||||
|
||||
if (convert_to_linear) {
|
||||
IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, colorspace);
|
||||
}
|
||||
|
||||
linearrgb_to_srgb_v3_v3(rgba, rgba);
|
||||
|
||||
clamp_v4(rgba, 0.0f, 1.0f);
|
||||
return has_rgb;
|
||||
}
|
||||
|
||||
void paint_stroke_operator_properties(wmOperatorType *ot)
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "BKE_scene.h"
|
||||
#include "BKE_subdiv_ccg.h"
|
||||
#include "BKE_subsurf.h"
|
||||
#include "BLI_math_vector.hh"
|
||||
|
||||
#include "NOD_texture.h"
|
||||
|
||||
|
@ -2555,80 +2556,12 @@ static float brush_strength(const Sculpt *sd,
|
|||
}
|
||||
}
|
||||
|
||||
float SCULPT_brush_strength_factor(SculptSession *ss,
|
||||
const Brush *br,
|
||||
const float brush_point[3],
|
||||
float len,
|
||||
const float vno[3],
|
||||
const float fno[3],
|
||||
float mask,
|
||||
const PBVHVertRef vertex,
|
||||
const int thread_id,
|
||||
AutomaskingNodeData *automask_data)
|
||||
static float sculpt_apply_hardness(const SculptSession *ss, const float input_len)
|
||||
{
|
||||
StrokeCache *cache = ss->cache;
|
||||
const Scene *scene = cache->vc->scene;
|
||||
const MTex *mtex = BKE_brush_mask_texture_get(br, OB_MODE_SCULPT);
|
||||
float avg = 1.0f;
|
||||
float rgba[4];
|
||||
float point[3];
|
||||
|
||||
sub_v3_v3v3(point, brush_point, cache->plane_offset);
|
||||
|
||||
if (!mtex->tex) {
|
||||
avg = 1.0f;
|
||||
}
|
||||
else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
|
||||
/* Get strength by feeding the vertex location directly into a texture. */
|
||||
avg = BKE_brush_sample_tex_3d(scene, br, mtex, point, rgba, 0, ss->tex_pool);
|
||||
}
|
||||
else {
|
||||
float symm_point[3], point_2d[2];
|
||||
/* Quite warnings. */
|
||||
float x = 0.0f, y = 0.0f;
|
||||
|
||||
/* If the active area is being applied for symmetry, flip it
|
||||
* across the symmetry axis and rotate it back to the original
|
||||
* position in order to project it. This insures that the
|
||||
* brush texture will be oriented correctly. */
|
||||
if (cache->radial_symmetry_pass) {
|
||||
mul_m4_v3(cache->symm_rot_mat_inv, point);
|
||||
}
|
||||
flip_v3_v3(symm_point, point, cache->mirror_symmetry_pass);
|
||||
|
||||
ED_view3d_project_float_v2_m4(cache->vc->region, symm_point, point_2d, cache->projection_mat);
|
||||
|
||||
/* Still no symmetry supported for other paint modes.
|
||||
* Sculpt does it DIY. */
|
||||
if (mtex->brush_map_mode == MTEX_MAP_MODE_AREA) {
|
||||
/* Similar to fixed mode, but projects from brush angle
|
||||
* rather than view direction. */
|
||||
|
||||
mul_m4_v3(cache->brush_local_mat, symm_point);
|
||||
|
||||
x = symm_point[0];
|
||||
y = symm_point[1];
|
||||
|
||||
x *= mtex->size[0];
|
||||
y *= mtex->size[1];
|
||||
|
||||
x += mtex->ofs[0];
|
||||
y += mtex->ofs[1];
|
||||
|
||||
avg = paint_get_tex_pixel(mtex, x, y, ss->tex_pool, thread_id);
|
||||
|
||||
avg += br->texture_sample_bias;
|
||||
}
|
||||
else {
|
||||
const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f};
|
||||
avg = BKE_brush_sample_tex_3d(scene, br, mtex, point_3d, rgba, 0, ss->tex_pool);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hardness. */
|
||||
float final_len = len;
|
||||
const StrokeCache *cache = ss->cache;
|
||||
float final_len = input_len;
|
||||
const float hardness = cache->paint_brush.hardness;
|
||||
float p = len / cache->radius;
|
||||
float p = input_len / cache->radius;
|
||||
if (p < hardness) {
|
||||
final_len = 0.0f;
|
||||
}
|
||||
|
@ -2640,9 +2573,100 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
|
|||
final_len = p * cache->radius;
|
||||
}
|
||||
|
||||
return final_len;
|
||||
}
|
||||
|
||||
static void sculpt_apply_texture(const SculptSession *ss,
|
||||
const Brush *brush,
|
||||
const float brush_point[3],
|
||||
const int thread_id,
|
||||
float *r_value,
|
||||
float r_rgba[4])
|
||||
{
|
||||
StrokeCache *cache = ss->cache;
|
||||
const Scene *scene = cache->vc->scene;
|
||||
const MTex *mtex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
|
||||
|
||||
if (!mtex->tex) {
|
||||
*r_value = 1.0f;
|
||||
copy_v4_fl(r_rgba, 1.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
float point[3];
|
||||
sub_v3_v3v3(point, brush_point, cache->plane_offset);
|
||||
|
||||
if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
|
||||
/* Get strength by feeding the vertex location directly into a texture. */
|
||||
*r_value = BKE_brush_sample_tex_3d(scene, brush, mtex, point, r_rgba, 0, ss->tex_pool);
|
||||
}
|
||||
else {
|
||||
float symm_point[3];
|
||||
|
||||
/* If the active area is being applied for symmetry, flip it
|
||||
* across the symmetry axis and rotate it back to the original
|
||||
* position in order to project it. This insures that the
|
||||
* brush texture will be oriented correctly. */
|
||||
if (cache->radial_symmetry_pass) {
|
||||
mul_m4_v3(cache->symm_rot_mat_inv, point);
|
||||
}
|
||||
flip_v3_v3(symm_point, point, cache->mirror_symmetry_pass);
|
||||
|
||||
/* Still no symmetry supported for other paint modes.
|
||||
* Sculpt does it DIY. */
|
||||
if (mtex->brush_map_mode == MTEX_MAP_MODE_AREA) {
|
||||
/* Similar to fixed mode, but projects from brush angle
|
||||
* rather than view direction. */
|
||||
|
||||
mul_m4_v3(cache->brush_local_mat, symm_point);
|
||||
|
||||
float x = symm_point[0];
|
||||
float y = symm_point[1];
|
||||
|
||||
x *= mtex->size[0];
|
||||
y *= mtex->size[1];
|
||||
|
||||
x += mtex->ofs[0];
|
||||
y += mtex->ofs[1];
|
||||
|
||||
paint_get_tex_pixel(mtex, x, y, ss->tex_pool, thread_id, r_value, r_rgba);
|
||||
|
||||
add_v3_fl(r_rgba, brush->texture_sample_bias); // v3 -> Ignore alpha
|
||||
*r_value -= brush->texture_sample_bias;
|
||||
}
|
||||
else {
|
||||
float point_2d[2];
|
||||
ED_view3d_project_float_v2_m4(
|
||||
cache->vc->region, symm_point, point_2d, cache->projection_mat);
|
||||
const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f};
|
||||
*r_value = BKE_brush_sample_tex_3d(scene, brush, mtex, point_3d, r_rgba, 0, ss->tex_pool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float SCULPT_brush_strength_factor(SculptSession *ss,
|
||||
const Brush *brush,
|
||||
const float brush_point[3],
|
||||
float len,
|
||||
const float vno[3],
|
||||
const float fno[3],
|
||||
float mask,
|
||||
const PBVHVertRef vertex,
|
||||
int thread_id,
|
||||
AutomaskingNodeData *automask_data)
|
||||
{
|
||||
StrokeCache *cache = ss->cache;
|
||||
|
||||
float avg = 1.0f;
|
||||
float rgba[4];
|
||||
sculpt_apply_texture(ss, brush, brush_point, thread_id, &avg, rgba);
|
||||
|
||||
/* Hardness. */
|
||||
const float final_len = sculpt_apply_hardness(ss, len);
|
||||
|
||||
/* Falloff curve. */
|
||||
avg *= BKE_brush_curve_strength(br, final_len, cache->radius);
|
||||
avg *= frontface(br, cache->view_normal, vno, fno);
|
||||
avg *= BKE_brush_curve_strength(brush, final_len, cache->radius);
|
||||
avg *= frontface(brush, cache->view_normal, vno, fno);
|
||||
|
||||
/* Paint mask. */
|
||||
avg *= 1.0f - mask;
|
||||
|
@ -2653,6 +2677,69 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
|
|||
return avg;
|
||||
}
|
||||
|
||||
void SCULPT_brush_strength_color(SculptSession *ss,
|
||||
const Brush *brush,
|
||||
const float brush_point[3],
|
||||
float len,
|
||||
const float vno[3],
|
||||
const float fno[3],
|
||||
float mask,
|
||||
const PBVHVertRef vertex,
|
||||
int thread_id,
|
||||
AutomaskingNodeData *automask_data,
|
||||
float r_rgba[4])
|
||||
{
|
||||
StrokeCache *cache = ss->cache;
|
||||
|
||||
float avg = 1.0f;
|
||||
sculpt_apply_texture(ss, brush, brush_point, thread_id, &avg, r_rgba);
|
||||
|
||||
/* Hardness. */
|
||||
const float final_len = sculpt_apply_hardness(ss, len);
|
||||
|
||||
/* Falloff curve. */
|
||||
const float falloff = BKE_brush_curve_strength(brush, final_len, cache->radius) *
|
||||
frontface(brush, cache->view_normal, vno, fno);
|
||||
|
||||
/* Paint mask. */
|
||||
const float paint_mask = 1.0f - mask;
|
||||
|
||||
/* Auto-masking. */
|
||||
const float automasking_factor = SCULPT_automasking_factor_get(
|
||||
cache->automasking, ss, vertex, automask_data);
|
||||
|
||||
const float masks_combined = falloff * paint_mask * automasking_factor;
|
||||
|
||||
mul_v4_fl(r_rgba, masks_combined);
|
||||
}
|
||||
|
||||
void SCULPT_calc_vertex_displacement(SculptSession *ss,
|
||||
const Brush *brush,
|
||||
float rgba[4],
|
||||
float out_offset[3])
|
||||
{
|
||||
mul_v3_fl(rgba, ss->cache->bstrength);
|
||||
/* Handle brush inversion */
|
||||
if (ss->cache->bstrength < 0) {
|
||||
rgba[0] *= -1;
|
||||
rgba[1] *= -1;
|
||||
}
|
||||
|
||||
/* Apply texture size */
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
rgba[i] *= blender::math::safe_divide(1.0f, pow2f(brush->mtex.size[i]));
|
||||
}
|
||||
|
||||
/* Transform vector to object space */
|
||||
mul_mat3_m4_v3(ss->cache->brush_local_mat_inv, rgba);
|
||||
|
||||
/* Handle symmetry */
|
||||
if (ss->cache->radial_symmetry_pass) {
|
||||
mul_m4_v3(ss->cache->symm_rot_mat, rgba);
|
||||
}
|
||||
flip_v3_v3(out_offset, rgba, ss->cache->mirror_symmetry_pass);
|
||||
}
|
||||
|
||||
bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v)
|
||||
{
|
||||
SculptSearchSphereData *data = static_cast<SculptSearchSphereData *>(data_v);
|
||||
|
@ -2920,7 +3007,10 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3])
|
|||
mul_m4_v3(ob->world_to_object, y);
|
||||
}
|
||||
|
||||
static void calc_brush_local_mat(const MTex *mtex, Object *ob, float local_mat[4][4])
|
||||
static void calc_brush_local_mat(const MTex *mtex,
|
||||
Object *ob,
|
||||
float local_mat[4][4],
|
||||
float local_mat_inv[4][4])
|
||||
{
|
||||
const StrokeCache *cache = ob->sculpt->cache;
|
||||
float tmat[4][4];
|
||||
|
@ -2966,6 +3056,8 @@ static void calc_brush_local_mat(const MTex *mtex, Object *ob, float local_mat[4
|
|||
scale_m4_fl(scale, radius);
|
||||
mul_m4_m4m4(tmat, mat, scale);
|
||||
|
||||
/* Return tmat as is (for converting from local area coords to model-space coords). */
|
||||
copy_m4_m4(local_mat_inv, tmat);
|
||||
/* Return inverse (for converting from model-space coords to local area coords). */
|
||||
invert_m4_m4(local_mat, tmat);
|
||||
}
|
||||
|
@ -3000,7 +3092,7 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob)
|
|||
if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0) {
|
||||
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
|
||||
calc_brush_local_mat(mask_tex, ob, cache->brush_local_mat);
|
||||
calc_brush_local_mat(mask_tex, ob, cache->brush_local_mat, cache->brush_local_mat_inv);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -265,18 +265,35 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata,
|
|||
SCULPT_automasking_node_update(ss, &automask_data, &vd);
|
||||
|
||||
/* Offset vertex. */
|
||||
const float fade = SCULPT_brush_strength_factor(ss,
|
||||
brush,
|
||||
vd.co,
|
||||
sqrtf(test.dist),
|
||||
vd.no,
|
||||
vd.fno,
|
||||
vd.mask ? *vd.mask : 0.0f,
|
||||
vd.vertex,
|
||||
thread_id,
|
||||
&automask_data);
|
||||
|
||||
mul_v3_v3fl(proxy[vd.i], offset, fade);
|
||||
if (ss->cache->brush->flag2 & BRUSH_USE_COLOR_AS_DISPLACEMENT &&
|
||||
(brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)) {
|
||||
float r_rgba[4];
|
||||
SCULPT_brush_strength_color(ss,
|
||||
brush,
|
||||
vd.co,
|
||||
sqrtf(test.dist),
|
||||
vd.no,
|
||||
vd.fno,
|
||||
vd.mask ? *vd.mask : 0.0f,
|
||||
vd.vertex,
|
||||
thread_id,
|
||||
&automask_data,
|
||||
r_rgba);
|
||||
SCULPT_calc_vertex_displacement(ss, brush, r_rgba, proxy[vd.i]);
|
||||
}
|
||||
else {
|
||||
float fade = SCULPT_brush_strength_factor(ss,
|
||||
brush,
|
||||
vd.co,
|
||||
sqrtf(test.dist),
|
||||
vd.no,
|
||||
vd.fno,
|
||||
vd.mask ? *vd.mask : 0.0f,
|
||||
vd.vertex,
|
||||
thread_id,
|
||||
&automask_data);
|
||||
mul_v3_v3fl(proxy[vd.i], offset, fade);
|
||||
}
|
||||
|
||||
if (vd.is_mesh) {
|
||||
BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex);
|
||||
|
|
|
@ -586,8 +586,13 @@ struct StrokeCache {
|
|||
float sculpt_normal_symm[3];
|
||||
|
||||
/* Used for area texture mode, local_mat gets calculated by
|
||||
* calc_brush_local_mat() and used in tex_strength(). */
|
||||
* calc_brush_local_mat() and used in sculpt_apply_texture().
|
||||
* Transforms from model-space coords to local area coords.
|
||||
*/
|
||||
float brush_local_mat[4][4];
|
||||
/* The matrix from local area coords to model-space coords is used to calculate the vector
|
||||
* displacement in area plane mode. */
|
||||
float brush_local_mat_inv[4][4];
|
||||
|
||||
float plane_offset[3]; /* used to shift the plane around when doing tiled strokes */
|
||||
int tile_pass;
|
||||
|
@ -1241,6 +1246,30 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
|
|||
int thread_id,
|
||||
AutomaskingNodeData *automask_data);
|
||||
|
||||
/**
|
||||
* Return a color of a brush texture on a particular vertex multiplied by active masks.
|
||||
*/
|
||||
void SCULPT_brush_strength_color(SculptSession *ss,
|
||||
const Brush *brush,
|
||||
const float brush_point[3],
|
||||
float len,
|
||||
const float vno[3],
|
||||
const float fno[3],
|
||||
float mask,
|
||||
const PBVHVertRef vertex,
|
||||
int thread_id,
|
||||
AutomaskingNodeData *automask_data,
|
||||
float r_rgba[4]);
|
||||
|
||||
/**
|
||||
* Calculates the vertex offset for a single vertex depending on the brush setting rgb as vector
|
||||
* displacement.
|
||||
*/
|
||||
void SCULPT_calc_vertex_displacement(SculptSession *ss,
|
||||
const Brush *brush,
|
||||
float rgba[3],
|
||||
float out_offset[3]);
|
||||
|
||||
/**
|
||||
* Tilts a normal by the x and y tilt values using the view axis.
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
#include "GPU_immediate_util.h"
|
||||
#include "GPU_state.h"
|
||||
|
||||
#include "AS_asset_representation.h"
|
||||
|
||||
#include "filelist.h"
|
||||
|
||||
#include "file_intern.h" /* own include */
|
||||
|
@ -126,6 +128,19 @@ static void draw_tile_background(const rcti *draw_rect, int colorid, int shade)
|
|||
UI_draw_roundbox_aa(&draw_rect_fl, true, 5.0f, color);
|
||||
}
|
||||
|
||||
static eFileAssetImportType get_asset_import_type(const SpaceFile *sfile, const FileDirEntry *file)
|
||||
{
|
||||
const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
|
||||
BLI_assert(asset_params != NULL);
|
||||
if (asset_params->import_type != FILE_ASSET_IMPORT_LINK) {
|
||||
return asset_params->import_type;
|
||||
}
|
||||
if (AS_asset_representation_is_never_link(file->asset)) {
|
||||
return FILE_ASSET_IMPORT_APPEND_REUSE;
|
||||
}
|
||||
return FILE_ASSET_IMPORT_LINK;
|
||||
}
|
||||
|
||||
static void file_draw_icon(const SpaceFile *sfile,
|
||||
uiBlock *block,
|
||||
const FileDirEntry *file,
|
||||
|
@ -165,13 +180,10 @@ static void file_draw_icon(const SpaceFile *sfile,
|
|||
ImBuf *preview_image = filelist_file_getimage(file);
|
||||
char blend_path[FILE_MAX_LIBEXTRA];
|
||||
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {
|
||||
const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
|
||||
BLI_assert(asset_params != NULL);
|
||||
|
||||
UI_but_drag_set_asset(but,
|
||||
&(AssetHandle){.file_data = file},
|
||||
BLI_strdup(blend_path),
|
||||
asset_params->import_type,
|
||||
get_asset_import_type(sfile, file),
|
||||
icon,
|
||||
preview_image,
|
||||
UI_DPI_FAC);
|
||||
|
@ -558,13 +570,10 @@ static void file_draw_preview(const SpaceFile *sfile,
|
|||
char blend_path[FILE_MAX_LIBEXTRA];
|
||||
|
||||
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {
|
||||
const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
|
||||
BLI_assert(asset_params != NULL);
|
||||
|
||||
UI_but_drag_set_asset(but,
|
||||
&(AssetHandle){.file_data = file},
|
||||
BLI_strdup(blend_path),
|
||||
asset_params->import_type,
|
||||
get_asset_import_type(sfile, file),
|
||||
icon,
|
||||
imb,
|
||||
scale);
|
||||
|
@ -986,7 +995,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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
#include "UI_interface_icons.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "AS_essentials_library.hh"
|
||||
|
||||
#include "file_intern.h"
|
||||
#include "filelist.h"
|
||||
|
||||
|
@ -102,7 +104,7 @@ static void fileselect_ensure_updated_asset_params(SpaceFile *sfile)
|
|||
asset_params = sfile->asset_params = static_cast<FileAssetSelectParams *>(
|
||||
MEM_callocN(sizeof(*asset_params), "FileAssetSelectParams"));
|
||||
asset_params->base_params.details_flags = U_default.file_space_data.details_flags;
|
||||
asset_params->asset_library_ref.type = ASSET_LIBRARY_LOCAL;
|
||||
asset_params->asset_library_ref.type = ASSET_LIBRARY_ALL;
|
||||
asset_params->asset_library_ref.custom_library_index = -1;
|
||||
asset_params->import_type = FILE_ASSET_IMPORT_APPEND_REUSE;
|
||||
}
|
||||
|
@ -420,11 +422,17 @@ static void fileselect_refresh_asset_params(FileAssetSelectParams *asset_params)
|
|||
user_library = BKE_preferences_asset_library_find_from_index(&U,
|
||||
library->custom_library_index);
|
||||
if (!user_library) {
|
||||
library->type = ASSET_LIBRARY_LOCAL;
|
||||
library->type = ASSET_LIBRARY_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (library->type) {
|
||||
switch (eAssetLibraryType(library->type)) {
|
||||
case ASSET_LIBRARY_ESSENTIALS:
|
||||
BLI_strncpy(base_params->dir,
|
||||
blender::asset_system::essentials_directory_path().c_str(),
|
||||
sizeof(base_params->dir));
|
||||
base_params->type = FILE_ASSET_LIBRARY;
|
||||
break;
|
||||
case ASSET_LIBRARY_ALL:
|
||||
base_params->dir[0] = '\0';
|
||||
base_params->type = FILE_ASSET_LIBRARY_ALL;
|
||||
|
@ -1124,7 +1132,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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1104,7 +1104,7 @@ static void draw_rotation_guide(const RegionView3D *rv3d)
|
|||
immUnbindProgram();
|
||||
|
||||
/* -- draw rotation center -- */
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
|
||||
immUniform1f("size", 7.0f);
|
||||
immBegin(GPU_PRIM_POINTS, 1);
|
||||
immAttr4ubv(col, color);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue