Refactoring: Geometry Node: Avoid copy last buffer in result for Blur Attribute node #106860
|
@ -815,64 +815,49 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
|||
string(PREPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO "${GCC_EXTRA_FLAGS_RELEASE} ")
|
||||
unset(GCC_EXTRA_FLAGS_RELEASE)
|
||||
|
||||
# NOTE(@campbellbarton): Eventually mold will be able to use `-fuse-ld=mold`,
|
||||
# however at the moment this only works for GCC 12.1+ (unreleased at time of writing).
|
||||
# So a workaround is used here "-B" which points to another path to find system commands
|
||||
# such as `ld`.
|
||||
if(WITH_LINKER_MOLD AND _IS_LINKER_DEFAULT)
|
||||
find_program(MOLD_BIN "mold")
|
||||
mark_as_advanced(MOLD_BIN)
|
||||
|
||||
if(NOT MOLD_BIN)
|
||||
message(STATUS "The \"mold\" binary could not be found, using system linker.")
|
||||
set(WITH_LINKER_MOLD OFF)
|
||||
elseif(CMAKE_C_COMPILER_VERSION VERSION_LESS 12.1)
|
||||
message(STATUS "GCC 12.1 or newer is required for th MOLD linker.")
|
||||
set(WITH_LINKER_MOLD OFF)
|
||||
else()
|
||||
# By default mold installs the binary to:
|
||||
# - `{PREFIX}/bin/mold` as well as a symbolic-link in...
|
||||
# - `{PREFIX}/lib/mold/ld`.
|
||||
# (where `PREFIX` is typically `/usr/`).
|
||||
#
|
||||
# This block of code finds `{PREFIX}/lib/mold` from the `mold` binary.
|
||||
# Other methods of searching for the path could also be made to work,
|
||||
# we could even make our own directory and symbolic-link, however it's more
|
||||
# convenient to use the one provided by mold.
|
||||
#
|
||||
# Use the binary path to "mold", to find the common prefix which contains "lib/mold".
|
||||
# The parent directory: e.g. `/usr/bin/mold` -> `/usr/bin/`.
|
||||
get_filename_component(MOLD_PREFIX "${MOLD_BIN}" DIRECTORY)
|
||||
# The common prefix path: e.g. `/usr/bin/` -> `/usr/` to use as a hint.
|
||||
get_filename_component(MOLD_PREFIX "${MOLD_PREFIX}" DIRECTORY)
|
||||
# Find `{PREFIX}/lib/mold/ld`, store the directory component (without the `ld`).
|
||||
# Then pass `-B {PREFIX}/lib/mold` to GCC so the `ld` located there overrides the default.
|
||||
find_path(
|
||||
MOLD_BIN_DIR "ld"
|
||||
HINTS "${MOLD_PREFIX}"
|
||||
# The default path is `libexec`, Arch Linux for e.g.
|
||||
# replaces this with `lib` so check both.
|
||||
PATH_SUFFIXES "libexec/mold" "lib/mold" "lib64/mold"
|
||||
NO_DEFAULT_PATH
|
||||
NO_CACHE
|
||||
get_filename_component(MOLD_BIN_DIR "${MOLD_BIN}" DIRECTORY)
|
||||
# Check if the `-B` argument is required.
|
||||
# This will happen when `MOLD_BIN` points to a non-standard location.
|
||||
# Keep this option as mold is not yet a standard system component and
|
||||
# users may have it installed in some unexpected place.
|
||||
set(_mold_args "-fuse-ld=mold")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_C_COMPILER} -B ${MOLD_BIN_DIR} ${_mold_args} -Wl,--version
|
||||
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION_WITH_DIR
|
||||
)
|
||||
if(NOT MOLD_BIN_DIR)
|
||||
message(STATUS
|
||||
"The mold linker could not find the directory containing the linker command "
|
||||
"(typically "
|
||||
"\"${MOLD_PREFIX}/libexec/mold/ld\") or "
|
||||
"\"${MOLD_PREFIX}/lib/mold/ld\") using system linker."
|
||||
)
|
||||
set(WITH_LINKER_MOLD OFF)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_C_COMPILER} ${_mold_args} -Wl,--version
|
||||
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION
|
||||
)
|
||||
if(NOT (LD_VERSION STREQUAL LD_VERSION_WITH_DIR))
|
||||
string(PREPEND _mold_args "-B \"${MOLD_BIN_DIR}\" ")
|
||||
set(LD_VERSION "${LD_VERSION_WITH_DIR}")
|
||||
endif()
|
||||
unset(MOLD_PREFIX)
|
||||
endif()
|
||||
|
||||
if(WITH_LINKER_MOLD)
|
||||
# GCC will search for `ld` in this directory first.
|
||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " -B \"${MOLD_BIN_DIR}\"")
|
||||
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -B \"${MOLD_BIN_DIR}\"")
|
||||
string(APPEND CMAKE_MODULE_LINKER_FLAGS " -B \"${MOLD_BIN_DIR}\"")
|
||||
set(_IS_LINKER_DEFAULT OFF)
|
||||
if("${LD_VERSION}" MATCHES "mold ")
|
||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${_mold_args}")
|
||||
string(APPEND CMAKE_SHARED_LINKER_FLAGS " ${_mold_args}")
|
||||
string(APPEND CMAKE_MODULE_LINKER_FLAGS " ${_mold_args}")
|
||||
set(_IS_LINKER_DEFAULT OFF)
|
||||
else()
|
||||
message(STATUS "GNU mold linker isn't available, using the default system linker.")
|
||||
endif()
|
||||
unset(_mold_args)
|
||||
unset(MOLD_BIN_DIR)
|
||||
unset(LD_VERSION)
|
||||
endif()
|
||||
unset(MOLD_BIN)
|
||||
unset(MOLD_BIN_DIR)
|
||||
endif()
|
||||
|
||||
if(WITH_LINKER_GOLD AND _IS_LINKER_DEFAULT)
|
||||
|
|
|
@ -172,6 +172,8 @@ def system_info():
|
|||
|
||||
|
||||
def list_render_passes(scene, srl):
|
||||
import _cycles
|
||||
|
||||
crl = srl.cycles
|
||||
|
||||
# Combined pass.
|
||||
|
@ -250,6 +252,12 @@ def list_render_passes(scene, srl):
|
|||
for lightgroup in srl.lightgroups:
|
||||
yield ("Combined_%s" % lightgroup.name, "RGB", 'COLOR')
|
||||
|
||||
# Path guiding debug passes.
|
||||
if _cycles.with_debug:
|
||||
yield ("Guiding Color", "RGB", 'COLOR')
|
||||
yield ("Guiding Probability", "X", 'VALUE')
|
||||
yield ("Guiding Average Roughness", "X", 'VALUE')
|
||||
|
||||
|
||||
def register_passes(engine, scene, view_layer):
|
||||
for name, channelids, channeltype in list_render_passes(scene, view_layer):
|
||||
|
|
|
@ -634,6 +634,10 @@ static bool get_known_pass_type(BL::RenderPass &b_pass, PassType &type, PassMode
|
|||
MAP_PASS("AdaptiveAuxBuffer", PASS_ADAPTIVE_AUX_BUFFER, false);
|
||||
MAP_PASS("Debug Sample Count", PASS_SAMPLE_COUNT, false);
|
||||
|
||||
MAP_PASS("Guiding Color", PASS_GUIDING_COLOR, false);
|
||||
MAP_PASS("Guiding Probability", PASS_GUIDING_PROBABILITY, false);
|
||||
MAP_PASS("Guiding Average Roughness", PASS_GUIDING_AVG_ROUGHNESS, false);
|
||||
|
||||
if (string_startswith(name, cryptomatte_prefix)) {
|
||||
type = PASS_CRYPTOMATTE;
|
||||
mode = PassMode::DENOISED;
|
||||
|
@ -684,18 +688,6 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
|
|||
}
|
||||
scene->film->set_cryptomatte_passes(cryptomatte_passes);
|
||||
|
||||
/* Path guiding debug passes. */
|
||||
#ifdef WITH_CYCLES_DEBUG
|
||||
b_engine.add_pass("Guiding Color", 3, "RGB", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_GUIDING_COLOR, "Guiding Color", PassMode::NOISY);
|
||||
|
||||
b_engine.add_pass("Guiding Probability", 1, "X", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_GUIDING_PROBABILITY, "Guiding Probability", PassMode::NOISY);
|
||||
|
||||
b_engine.add_pass("Guiding Average Roughness", 1, "X", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_GUIDING_AVG_ROUGHNESS, "Guiding Average Roughness", PassMode::NOISY);
|
||||
#endif
|
||||
|
||||
unordered_set<string> expected_passes;
|
||||
|
||||
/* Custom AOV passes. */
|
||||
|
|
|
@ -357,8 +357,12 @@ void PathTraceWorkCPU::guiding_push_sample_data_to_global_storage(
|
|||
# if PATH_GUIDING_LEVEL >= 2
|
||||
const bool use_direct_light = kernel_data.integrator.use_guiding_direct_light;
|
||||
const bool use_mis_weights = kernel_data.integrator.use_guiding_mis_weights;
|
||||
# if OPENPGL_VERSION_MINOR >= 5
|
||||
kg->opgl_path_segment_storage->PrepareSamples(use_mis_weights, use_direct_light, false);
|
||||
# else
|
||||
kg->opgl_path_segment_storage->PrepareSamples(
|
||||
false, nullptr, use_mis_weights, use_direct_light, false);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef WITH_CYCLES_DEBUG
|
||||
|
|
|
@ -454,8 +454,13 @@ ccl_device_forceinline bool guiding_bsdf_init(KernelGlobals kg,
|
|||
ccl_private float &rand)
|
||||
{
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
# if OPENPGL_VERSION_MINOR >= 5
|
||||
if (kg->opgl_surface_sampling_distribution->Init(
|
||||
kg->opgl_guiding_field, guiding_point3f(P), rand)) {
|
||||
# else
|
||||
if (kg->opgl_surface_sampling_distribution->Init(
|
||||
kg->opgl_guiding_field, guiding_point3f(P), rand, true)) {
|
||||
# endif
|
||||
kg->opgl_surface_sampling_distribution->ApplyCosineProduct(guiding_point3f(N));
|
||||
return true;
|
||||
}
|
||||
|
@ -506,8 +511,13 @@ ccl_device_forceinline bool guiding_phase_init(KernelGlobals kg,
|
|||
return false;
|
||||
}
|
||||
|
||||
# if OPENPGL_VERSION_MINOR >= 5
|
||||
if (kg->opgl_volume_sampling_distribution->Init(
|
||||
kg->opgl_guiding_field, guiding_point3f(P), rand)) {
|
||||
# else
|
||||
if (kg->opgl_volume_sampling_distribution->Init(
|
||||
kg->opgl_guiding_field, guiding_point3f(P), rand, true)) {
|
||||
# endif
|
||||
kg->opgl_volume_sampling_distribution->ApplySingleLobeHenyeyGreensteinProduct(guiding_vec3f(D),
|
||||
g);
|
||||
return true;
|
||||
|
|
|
@ -1390,19 +1390,128 @@ ccl_device_extern void osl_noiseparams_set_impulses(ccl_private OSLNoiseOptions
|
|||
res->y = n; \
|
||||
res->z = n; \
|
||||
} \
|
||||
ccl_device_extern void name##_vv(ccl_private float3 *res, const float3 *v) \
|
||||
ccl_device_extern void name##_vv(ccl_private float3 *res, ccl_private const float3 *v) \
|
||||
{ \
|
||||
const float n = name##_fv(v); \
|
||||
res->x = n; \
|
||||
res->y = n; \
|
||||
res->z = n; \
|
||||
} \
|
||||
ccl_device_extern void name##_vvf(ccl_private float3 *res, const float3 *v, float w) \
|
||||
ccl_device_extern void name##_vvf( \
|
||||
ccl_private float3 *res, ccl_private const float3 *v, float w) \
|
||||
{ \
|
||||
const float n = name##_fvf(v, w); \
|
||||
res->x = n; \
|
||||
res->y = n; \
|
||||
res->z = n; \
|
||||
} \
|
||||
ccl_device_extern void name##_dfdf(ccl_private float *res, ccl_private const float *x) \
|
||||
{ \
|
||||
res[0] = name##_ff(x[0]); \
|
||||
res[1] = name##_ff(x[1]); \
|
||||
res[2] = name##_ff(x[2]); \
|
||||
} \
|
||||
ccl_device_extern void name##_dfdff( \
|
||||
ccl_private float *res, ccl_private const float *x, float y) \
|
||||
{ \
|
||||
res[0] = name##_fff(x[0], y); \
|
||||
res[1] = name##_fff(x[1], y); \
|
||||
res[2] = name##_fff(x[2], y); \
|
||||
} \
|
||||
ccl_device_extern void name##_dffdf( \
|
||||
ccl_private float *res, float x, ccl_private const float *y) \
|
||||
{ \
|
||||
res[0] = name##_fff(x, y[0]); \
|
||||
res[1] = name##_fff(x, y[1]); \
|
||||
res[2] = name##_fff(x, y[2]); \
|
||||
} \
|
||||
ccl_device_extern void name##_dfdfdf( \
|
||||
ccl_private float *res, ccl_private const float *x, ccl_private const float *y) \
|
||||
{ \
|
||||
res[0] = name##_fff(x[0], y[0]); \
|
||||
res[1] = name##_fff(x[1], y[1]); \
|
||||
res[2] = name##_fff(x[2], y[2]); \
|
||||
} \
|
||||
ccl_device_extern void name##_dfdv(ccl_private float *res, ccl_private const float3 *v) \
|
||||
{ \
|
||||
res[0] = name##_fv(&v[0]); \
|
||||
res[1] = name##_fv(&v[1]); \
|
||||
res[2] = name##_fv(&v[2]); \
|
||||
} \
|
||||
ccl_device_extern void name##_dfdvf( \
|
||||
ccl_private float *res, ccl_private const float3 *v, float w) \
|
||||
{ \
|
||||
res[0] = name##_fvf(&v[0], w); \
|
||||
res[1] = name##_fvf(&v[1], w); \
|
||||
res[2] = name##_fvf(&v[2], w); \
|
||||
} \
|
||||
ccl_device_extern void name##_dfvdf( \
|
||||
ccl_private float *res, ccl_private const float3 *v, ccl_private const float *w) \
|
||||
{ \
|
||||
res[0] = name##_fvf(v, w[0]); \
|
||||
res[1] = name##_fvf(v, w[1]); \
|
||||
res[2] = name##_fvf(v, w[2]); \
|
||||
} \
|
||||
ccl_device_extern void name##_dfdvdf( \
|
||||
ccl_private float *res, ccl_private const float3 *v, ccl_private const float *w) \
|
||||
{ \
|
||||
res[0] = name##_fvf(&v[0], w[0]); \
|
||||
res[1] = name##_fvf(&v[1], w[1]); \
|
||||
res[2] = name##_fvf(&v[2], w[2]); \
|
||||
} \
|
||||
ccl_device_extern void name##_dvdf(ccl_private float3 *res, ccl_private const float *x) \
|
||||
{ \
|
||||
name##_vf(&res[0], x[0]); \
|
||||
name##_vf(&res[1], x[1]); \
|
||||
name##_vf(&res[2], x[2]); \
|
||||
} \
|
||||
ccl_device_extern void name##_dvdff( \
|
||||
ccl_private float3 *res, ccl_private const float *x, float y) \
|
||||
{ \
|
||||
name##_vff(&res[0], x[0], y); \
|
||||
name##_vff(&res[1], x[1], y); \
|
||||
name##_vff(&res[2], x[2], y); \
|
||||
} \
|
||||
ccl_device_extern void name##_dvfdf( \
|
||||
ccl_private float3 *res, float x, ccl_private const float *y) \
|
||||
{ \
|
||||
name##_vff(&res[0], x, y[0]); \
|
||||
name##_vff(&res[1], x, y[1]); \
|
||||
name##_vff(&res[2], x, y[2]); \
|
||||
} \
|
||||
ccl_device_extern void name##_dvdfdf( \
|
||||
ccl_private float3 *res, ccl_private const float *x, ccl_private const float *y) \
|
||||
{ \
|
||||
name##_vff(&res[0], x[0], y[0]); \
|
||||
name##_vff(&res[1], x[1], y[1]); \
|
||||
name##_vff(&res[2], x[2], y[2]); \
|
||||
} \
|
||||
ccl_device_extern void name##_dvdv(ccl_private float3 *res, ccl_private const float3 *v) \
|
||||
{ \
|
||||
name##_vv(&res[0], &v[0]); \
|
||||
name##_vv(&res[1], &v[1]); \
|
||||
name##_vv(&res[2], &v[2]); \
|
||||
} \
|
||||
ccl_device_extern void name##_dvdvf( \
|
||||
ccl_private float3 *res, ccl_private const float3 *v, float w) \
|
||||
{ \
|
||||
name##_vvf(&res[0], &v[0], w); \
|
||||
name##_vvf(&res[1], &v[1], w); \
|
||||
name##_vvf(&res[2], &v[2], w); \
|
||||
} \
|
||||
ccl_device_extern void name##_dvvdf( \
|
||||
ccl_private float3 *res, ccl_private const float3 *v, ccl_private const float *w) \
|
||||
{ \
|
||||
name##_vvf(&res[0], v, w[0]); \
|
||||
name##_vvf(&res[1], v, w[1]); \
|
||||
name##_vvf(&res[2], v, w[2]); \
|
||||
} \
|
||||
ccl_device_extern void name##_dvdvdf( \
|
||||
ccl_private float3 *res, ccl_private const float3 *v, ccl_private const float *w) \
|
||||
{ \
|
||||
name##_vvf(&res[0], &v[0], w[0]); \
|
||||
name##_vvf(&res[1], &v[1], w[1]); \
|
||||
name##_vvf(&res[2], &v[2], w[2]); \
|
||||
}
|
||||
|
||||
ccl_device_forceinline float hashnoise_1d(float p)
|
||||
|
|
|
@ -1400,7 +1400,9 @@ bool GHOST_SystemCocoa::handleOpenDocumentRequest(void *filepathStr)
|
|||
[[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
GHOST_Window *window = (GHOST_Window *)m_windowManager->getActiveWindow();
|
||||
GHOST_Window *window = m_windowManager->getWindows().empty() ?
|
||||
NULL :
|
||||
(GHOST_Window *)m_windowManager->getWindows().front();
|
||||
|
||||
if (!window) {
|
||||
return NO;
|
||||
|
|
|
@ -1978,16 +1978,6 @@ bool GHOST_WindowWayland::outputs_changed_update_scale()
|
|||
fractional_scale_next = fractional_scale_from_output;
|
||||
scale_next = fractional_scale_next / FRACTIONAL_DENOMINATOR;
|
||||
}
|
||||
else {
|
||||
/* NOTE(@ideasman42): This often overrides #wp_fractional_scale_v1_listener::preferred_scale
|
||||
* in favor of using the greatest overlapping scale.
|
||||
* This was requested by the studio to prevent a tablet's built-in display of 75%
|
||||
* from causing the main-display being up-scaled (showing pixelated). */
|
||||
if (fractional_scale_next < fractional_scale_from_output) {
|
||||
fractional_scale_next = fractional_scale_from_output;
|
||||
scale_next = fractional_scale_next / FRACTIONAL_DENOMINATOR;
|
||||
}
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ def expand(line, cursor, namespace, *, private=True):
|
|||
[white_space + m[len(word_prefix):]
|
||||
if (word_prefix and m.startswith(word_prefix))
|
||||
else
|
||||
white_space + m.split('.')[-1]
|
||||
white_space + m.rsplit('.', 1)[-1]
|
||||
for m in matches])
|
||||
|
||||
no_calltip = True
|
||||
|
|
|
@ -28,7 +28,7 @@ def rna_backup_gen(data, include_props=None, exclude_props=None, root=()):
|
|||
# only writable properties...
|
||||
for p in data.bl_rna.properties:
|
||||
pid = p.identifier
|
||||
if pid == "rna_type" or pid == "original":
|
||||
if pid in {"rna_type", "original"}:
|
||||
continue
|
||||
path = root + (pid,)
|
||||
if include_props is not None and path not in include_props:
|
||||
|
|
|
@ -94,9 +94,7 @@ def keyconfig_test(kc):
|
|||
if testEntry(kc, child, src, parent):
|
||||
result = True
|
||||
else:
|
||||
for i in range(len(km.keymap_items)):
|
||||
src = km.keymap_items[i]
|
||||
|
||||
for i, src in enumerate(km.keymap_items):
|
||||
for child in children:
|
||||
if testEntry(kc, child, src, km):
|
||||
result = True
|
||||
|
|
|
@ -417,7 +417,7 @@ def ngon_tessellate(from_data, indices, fix_loops=True, debug_print=True):
|
|||
|
||||
if not flip:
|
||||
for i, fi in enumerate(fill):
|
||||
fill[i] = tuple([ii for ii in reversed(fi)])
|
||||
fill[i] = tuple(reversed(fi))
|
||||
|
||||
return fill
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
__all__ = (
|
||||
"connect_virtual_socket",
|
||||
"find_node_input",
|
||||
)
|
||||
|
||||
|
|
|
@ -5600,9 +5600,13 @@ def km_font(params):
|
|||
("font.move_select", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True},
|
||||
{"properties": [("type", 'NEXT_PAGE')]}),
|
||||
("font.change_spacing", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True, "repeat": True},
|
||||
{"properties": [("delta", -1)]}),
|
||||
{"properties": [("delta", -1.0)]}),
|
||||
("font.change_spacing", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True, "repeat": True},
|
||||
{"properties": [("delta", 1)]}),
|
||||
{"properties": [("delta", 1.0)]}),
|
||||
("font.change_spacing", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "alt": True, "repeat": True},
|
||||
{"properties": [("delta", -0.1)]}),
|
||||
("font.change_spacing", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "alt": True, "repeat": True},
|
||||
{"properties": [("delta", 0.1)]}),
|
||||
("font.change_character", {"type": 'UP_ARROW', "value": 'PRESS', "alt": True, "repeat": True},
|
||||
{"properties": [("delta", 1)]}),
|
||||
("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True},
|
||||
|
|
|
@ -239,7 +239,6 @@ def find_next(ele_dst, ele_src):
|
|||
|
||||
# expose for operators
|
||||
def select_next(bm, report):
|
||||
import bmesh
|
||||
ele_pair = [None, None]
|
||||
for i, ele in enumerate(reversed(bm.select_history)):
|
||||
ele_pair[i] = ele
|
||||
|
|
|
@ -488,7 +488,7 @@ class CLIP_OT_constraint_to_fcurve(Operator):
|
|||
efra = max(efra, track.markers[-1].frame)
|
||||
|
||||
if sfra is None or efra is None:
|
||||
return
|
||||
return {'CANCELLED'}
|
||||
|
||||
# Store object matrices.
|
||||
for x in range(sfra, efra + 1):
|
||||
|
@ -516,6 +516,8 @@ class CLIP_OT_constraint_to_fcurve(Operator):
|
|||
|
||||
scene.frame_set(frame_current)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
# XXX, should probably use context.selected_editable_objects
|
||||
|
@ -662,8 +664,7 @@ class CLIP_OT_setup_tracking_scene(Operator):
|
|||
if collection.collection.name == collection_name:
|
||||
setattr(collection, attr_name, True)
|
||||
break
|
||||
else:
|
||||
setup_collection_recursively(collection.children, collection_name, attr_name)
|
||||
setup_collection_recursively(collection.children, collection_name, attr_name)
|
||||
|
||||
collections = context.scene.collection.children
|
||||
vlayers = context.scene.view_layers
|
||||
|
|
|
@ -101,9 +101,9 @@ class MeshMirrorUV(Operator):
|
|||
for i, j in pmap.items():
|
||||
if not puvsel[i] or not puvsel[j]:
|
||||
continue
|
||||
elif DIR == 0 and pcents[i][0] < 0.0:
|
||||
if DIR == 0 and pcents[i][0] < 0.0:
|
||||
continue
|
||||
elif DIR == 1 and pcents[i][0] > 0.0:
|
||||
if DIR == 1 and pcents[i][0] > 0.0:
|
||||
continue
|
||||
|
||||
# copy UVs
|
||||
|
|
|
@ -9,8 +9,6 @@ from bpy.types import (
|
|||
from bpy.props import (
|
||||
BoolProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
IntProperty,
|
||||
StringProperty,
|
||||
)
|
||||
|
||||
|
|
|
@ -476,7 +476,7 @@ class QuickSmoke(ObjectModeOperator, Operator):
|
|||
# setup smoke domain
|
||||
bpy.ops.object.modifier_add(type='FLUID')
|
||||
obj.modifiers[-1].fluid_type = 'DOMAIN'
|
||||
if self.style == 'FIRE' or self.style == 'BOTH':
|
||||
if self.style == {'FIRE', 'BOTH'}:
|
||||
obj.modifiers[-1].domain_settings.use_noise = True
|
||||
|
||||
# ensure correct cache file format for smoke
|
||||
|
|
|
@ -22,8 +22,11 @@ def randomize_selected(context, seed, delta,
|
|||
obj.delta_location += rand_vec(loc)
|
||||
else:
|
||||
obj.location += rand_vec(loc)
|
||||
else: # otherwise the values change under us
|
||||
uniform(0.0, 0.0), uniform(0.0, 0.0), uniform(0.0, 0.0)
|
||||
else:
|
||||
# Otherwise the values change under us.
|
||||
uniform(0.0, 0.0)
|
||||
uniform(0.0, 0.0)
|
||||
uniform(0.0, 0.0)
|
||||
|
||||
if rot:
|
||||
vec = rand_vec(rot)
|
||||
|
@ -68,7 +71,9 @@ def randomize_selected(context, seed, delta,
|
|||
else:
|
||||
obj.scale = aX, aY, aZ
|
||||
else:
|
||||
uniform(0.0, 0.0), uniform(0.0, 0.0), uniform(0.0, 0.0)
|
||||
uniform(0.0, 0.0)
|
||||
uniform(0.0, 0.0)
|
||||
uniform(0.0, 0.0)
|
||||
|
||||
|
||||
from bpy.props import (
|
||||
|
|
|
@ -8,6 +8,7 @@ from bpy.app.translations import pgettext_tip as tip_
|
|||
|
||||
|
||||
def guess_player_path(preset):
|
||||
import os
|
||||
import sys
|
||||
|
||||
if preset == 'INTERNAL':
|
||||
|
|
|
@ -1170,7 +1170,7 @@ class PREFERENCES_OT_script_directory_new(Operator):
|
|||
new_dir.directory = self.directory
|
||||
new_dir.name = os.path.basename(self.directory.rstrip(os.sep))
|
||||
|
||||
assert context.preferences.is_dirty == True
|
||||
assert context.preferences.is_dirty is True
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
@ -1197,10 +1197,11 @@ class PREFERENCES_OT_script_directory_remove(Operator):
|
|||
script_directories.remove(script_directory)
|
||||
break
|
||||
|
||||
assert context.preferences.is_dirty == True
|
||||
assert context.preferences.is_dirty is True
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
classes = (
|
||||
PREFERENCES_OT_addon_disable,
|
||||
PREFERENCES_OT_addon_enable,
|
||||
|
|
|
@ -220,8 +220,6 @@ def lightmap_uvpack(
|
|||
PREF_SEL_ONLY=True,
|
||||
PREF_NEW_UVLAYER=False,
|
||||
PREF_PACK_IN_ONE=False,
|
||||
PREF_APPLY_IMAGE=False,
|
||||
PREF_IMG_PX_SIZE=512,
|
||||
PREF_BOX_DIV=8,
|
||||
PREF_MARGIN_DIV=512,
|
||||
):
|
||||
|
@ -240,8 +238,6 @@ def lightmap_uvpack(
|
|||
t = time.time()
|
||||
|
||||
if PREF_PACK_IN_ONE:
|
||||
if PREF_APPLY_IMAGE:
|
||||
image = bpy.data.images.new(name="lightmap", width=PREF_IMG_PX_SIZE, height=PREF_IMG_PX_SIZE, alpha=False)
|
||||
face_groups = [[]]
|
||||
else:
|
||||
face_groups = []
|
||||
|
@ -520,20 +516,6 @@ def lightmap_uvpack(
|
|||
# pf.place(box[1][1], box[1][2], packWidth, packHeight, margin_w, margin_h)
|
||||
print("done")
|
||||
|
||||
if PREF_APPLY_IMAGE:
|
||||
pass
|
||||
# removed with texface
|
||||
'''
|
||||
if not PREF_PACK_IN_ONE:
|
||||
image = bpy.data.images.new(name="lightmap",
|
||||
width=PREF_IMG_PX_SIZE,
|
||||
height=PREF_IMG_PX_SIZE,
|
||||
)
|
||||
|
||||
for f in face_sel:
|
||||
f.image = image
|
||||
'''
|
||||
|
||||
for me in meshes:
|
||||
me.update()
|
||||
|
||||
|
@ -544,11 +526,14 @@ def unwrap(operator, context, **kwargs):
|
|||
# switch to object mode
|
||||
is_editmode = context.object and context.object.mode == 'EDIT'
|
||||
if is_editmode:
|
||||
objects = context.objects_in_mode_unique_data
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
else:
|
||||
objects = context.selected_objects
|
||||
|
||||
# define list of meshes
|
||||
meshes = list({
|
||||
me for obj in context.selected_objects
|
||||
me for obj in objects
|
||||
if obj.type == 'MESH'
|
||||
if (me := obj.data).polygons and me.library is None
|
||||
})
|
||||
|
@ -606,20 +591,6 @@ class LightMapPack(Operator):
|
|||
description="Create a new UV map for every mesh packed",
|
||||
default=False,
|
||||
)
|
||||
PREF_APPLY_IMAGE: BoolProperty(
|
||||
name="New Image",
|
||||
description=(
|
||||
"Assign new images for every mesh (only one if "
|
||||
"Share Texture Space is enabled)"
|
||||
),
|
||||
default=False,
|
||||
)
|
||||
PREF_IMG_PX_SIZE: IntProperty(
|
||||
name="Image Size",
|
||||
description="Width and height for the new image",
|
||||
min=64, max=5000,
|
||||
default=512,
|
||||
)
|
||||
# UV Packing...
|
||||
PREF_BOX_DIV: IntProperty(
|
||||
name="Pack Quality",
|
||||
|
@ -648,8 +619,6 @@ class LightMapPack(Operator):
|
|||
|
||||
layout.prop(self, "PREF_PACK_IN_ONE")
|
||||
layout.prop(self, "PREF_NEW_UVLAYER")
|
||||
layout.prop(self, "PREF_APPLY_IMAGE")
|
||||
layout.prop(self, "PREF_IMG_PX_SIZE")
|
||||
layout.prop(self, "PREF_BOX_DIV")
|
||||
layout.prop(self, "PREF_MARGIN_DIV")
|
||||
|
||||
|
|
|
@ -120,15 +120,15 @@ def _draw_add_remove_buttons(
|
|||
list_length,
|
||||
):
|
||||
"""Draw the +/- buttons to add and remove list entries."""
|
||||
add_op = layout.operator(UILIST_OT_entry_add.bl_idname, text="", icon='ADD')
|
||||
add_op.list_path = list_path
|
||||
add_op.active_index_path = active_index_path
|
||||
props = layout.operator(UILIST_OT_entry_add.bl_idname, text="", icon='ADD')
|
||||
props.list_path = list_path
|
||||
props.active_index_path = active_index_path
|
||||
|
||||
row = layout.row()
|
||||
row.enabled = list_length > 0
|
||||
remove_op = row.operator(UILIST_OT_entry_remove.bl_idname, text="", icon='REMOVE')
|
||||
remove_op.list_path = list_path
|
||||
remove_op.active_index_path = active_index_path
|
||||
props = row.operator(UILIST_OT_entry_remove.bl_idname, text="", icon='REMOVE')
|
||||
props.list_path = list_path
|
||||
props.active_index_path = active_index_path
|
||||
|
||||
|
||||
def _draw_move_buttons(
|
||||
|
@ -141,15 +141,15 @@ def _draw_move_buttons(
|
|||
"""Draw the up/down arrows to move elements in the list."""
|
||||
col = layout.column()
|
||||
col.enabled = list_length > 1
|
||||
move_up_op = layout.operator(UILIST_OT_entry_move.bl_idname, text="", icon='TRIA_UP')
|
||||
move_up_op.direction = 'UP'
|
||||
move_up_op.list_path = list_path
|
||||
move_up_op.active_index_path = active_index_path
|
||||
props = layout.operator(UILIST_OT_entry_move.bl_idname, text="", icon='TRIA_UP')
|
||||
props.direction = 'UP'
|
||||
props.list_path = list_path
|
||||
props.active_index_path = active_index_path
|
||||
|
||||
move_down_op = layout.operator(UILIST_OT_entry_move.bl_idname, text="", icon='TRIA_DOWN')
|
||||
move_down_op.direction = 'DOWN'
|
||||
move_down_op.list_path = list_path
|
||||
move_down_op.active_index_path = active_index_path
|
||||
props = layout.operator(UILIST_OT_entry_move.bl_idname, text="", icon='TRIA_DOWN')
|
||||
props.direction = 'DOWN'
|
||||
props.list_path = list_path
|
||||
props.active_index_path = active_index_path
|
||||
|
||||
|
||||
def _get_context_attr(context, data_path):
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
import bpy
|
||||
from bpy.types import Menu
|
||||
from bpy.app.translations import (
|
||||
pgettext_iface as iface_,
|
||||
contexts as i18n_contexts,
|
||||
|
|
|
@ -423,13 +423,13 @@ class NODE_MT_geometry_node_mesh_topology(Menu):
|
|||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfFace"),
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfVertex"),
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfCorner"),
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfVertex"),
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeFaceOfCorner"),
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeOffsetCornerInFace"),
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeVertexOfCorner"),
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfFace")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfVertex")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfCorner")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfVertex")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeFaceOfCorner")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeOffsetCornerInFace")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeVertexOfCorner")
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
|
|
|
@ -63,12 +63,12 @@ class MESH_MT_shape_key_context_menu(Menu):
|
|||
layout.operator("object.join_shapes")
|
||||
layout.operator("object.shape_key_transfer")
|
||||
layout.separator()
|
||||
op = layout.operator("object.shape_key_remove", icon='X', text="Delete All Shape Keys")
|
||||
op.all = True
|
||||
op.apply_mix = False
|
||||
op = layout.operator("object.shape_key_remove", text="Apply All Shape Keys")
|
||||
op.all = True
|
||||
op.apply_mix = True
|
||||
props = layout.operator("object.shape_key_remove", icon='X', text="Delete All Shape Keys")
|
||||
props.all = True
|
||||
props.apply_mix = False
|
||||
props = layout.operator("object.shape_key_remove", text="Apply All Shape Keys")
|
||||
props.all = True
|
||||
props.apply_mix = True
|
||||
layout.separator()
|
||||
layout.operator("object.shape_key_move", icon='TRIA_UP_BAR', text="Move to Top").type = 'TOP'
|
||||
layout.operator("object.shape_key_move", icon='TRIA_DOWN_BAR', text="Move to Bottom").type = 'BOTTOM'
|
||||
|
@ -674,12 +674,12 @@ class MESH_UL_color_attributes(UIList, ColorAttributesListBase):
|
|||
|
||||
row = layout.row()
|
||||
row.emboss = 'NONE'
|
||||
prop = row.operator(
|
||||
props = row.operator(
|
||||
"geometry.color_attribute_render_set",
|
||||
text="",
|
||||
icon='RESTRICT_RENDER_OFF' if active_render else 'RESTRICT_RENDER_ON',
|
||||
)
|
||||
prop.name = attribute.name
|
||||
props.name = attribute.name
|
||||
|
||||
|
||||
class MESH_UL_color_attributes_selector(UIList, ColorAttributesListBase):
|
||||
|
|
|
@ -739,15 +739,15 @@ class VIEWLAYER_PT_freestyle_linestyle_color(ViewLayerFreestyleLineStyle, Panel)
|
|||
elif modifier.type == 'DISTANCE_FROM_OBJECT':
|
||||
box.prop(modifier, "target")
|
||||
draw_modifier_color_ramp_common(box, modifier, True)
|
||||
prop = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
prop.type = 'COLOR'
|
||||
prop.name = modifier.name
|
||||
props = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
props.type = 'COLOR'
|
||||
props.name = modifier.name
|
||||
|
||||
elif modifier.type == 'DISTANCE_FROM_CAMERA':
|
||||
draw_modifier_color_ramp_common(box, modifier, True)
|
||||
prop = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
prop.type = 'COLOR'
|
||||
prop.name = modifier.name
|
||||
props = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
props.type = 'COLOR'
|
||||
props.name = modifier.name
|
||||
|
||||
elif modifier.type == 'MATERIAL':
|
||||
row = box.row()
|
||||
|
@ -842,15 +842,15 @@ class VIEWLAYER_PT_freestyle_linestyle_alpha(ViewLayerFreestyleLineStyle, Panel)
|
|||
elif modifier.type == 'DISTANCE_FROM_OBJECT':
|
||||
box.prop(modifier, "target")
|
||||
draw_modifier_curve_common(box, modifier, True, False)
|
||||
prop = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
prop.type = 'ALPHA'
|
||||
prop.name = modifier.name
|
||||
props = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
props.type = 'ALPHA'
|
||||
props.name = modifier.name
|
||||
|
||||
elif modifier.type == 'DISTANCE_FROM_CAMERA':
|
||||
draw_modifier_curve_common(box, modifier, True, False)
|
||||
prop = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
prop.type = 'ALPHA'
|
||||
prop.name = modifier.name
|
||||
props = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
props.type = 'ALPHA'
|
||||
props.name = modifier.name
|
||||
|
||||
elif modifier.type == 'MATERIAL':
|
||||
box.prop(modifier, "material_attribute", text="Material Attribute")
|
||||
|
@ -934,15 +934,15 @@ class VIEWLAYER_PT_freestyle_linestyle_thickness(ViewLayerFreestyleLineStyle, Pa
|
|||
elif modifier.type == 'DISTANCE_FROM_OBJECT':
|
||||
box.prop(modifier, "target")
|
||||
draw_modifier_curve_common(box, modifier, True, True)
|
||||
prop = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
prop.type = 'THICKNESS'
|
||||
prop.name = modifier.name
|
||||
props = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
props.type = 'THICKNESS'
|
||||
props.name = modifier.name
|
||||
|
||||
elif modifier.type == 'DISTANCE_FROM_CAMERA':
|
||||
draw_modifier_curve_common(box, modifier, True, True)
|
||||
prop = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
prop.type = 'THICKNESS'
|
||||
prop.name = modifier.name
|
||||
props = box.operator("scene.freestyle_fill_range_by_selection")
|
||||
props.type = 'THICKNESS'
|
||||
props.name = modifier.name
|
||||
|
||||
elif modifier.type == 'MATERIAL':
|
||||
box.prop(modifier, "material_attribute", text="Material Attribute")
|
||||
|
|
|
@ -106,10 +106,14 @@ class GreasePencilDisplayPanel:
|
|||
settings = tool_settings.gpencil_vertex_paint
|
||||
brush = settings.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
|
||||
ob = context.active_object
|
||||
if ob.mode == 'PAINT_GPENCIL':
|
||||
|
||||
if self.is_popover and ob.mode not in {'PAINT_GPENCIL', 'VERTEX_GPENCIL'}:
|
||||
row = layout.row(align=True)
|
||||
row.use_property_split = False
|
||||
row.prop(settings, "show_brush", text="Display Cursor")
|
||||
|
||||
if ob.mode == 'PAINT_GPENCIL':
|
||||
if self.is_popover:
|
||||
row = layout.row(align=True)
|
||||
row.prop(settings, "show_brush", text="Display Cursor")
|
||||
|
@ -135,8 +139,7 @@ class GreasePencilDisplayPanel:
|
|||
|
||||
elif ob.mode == 'VERTEX_GPENCIL':
|
||||
row = layout.row(align=True)
|
||||
row.prop(settings, "show_brush", text="")
|
||||
row.label(text="Display Cursor")
|
||||
row.prop(settings, "show_brush", text="Display Cursor")
|
||||
|
||||
|
||||
class GreasePencilBrushFalloff:
|
||||
|
@ -145,16 +148,16 @@ class GreasePencilBrushFalloff:
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ts = context.tool_settings
|
||||
tool_settings = context.tool_settings
|
||||
settings = None
|
||||
if context.mode == 'PAINT_GPENCIL':
|
||||
settings = ts.gpencil_paint
|
||||
settings = tool_settings.gpencil_paint
|
||||
if context.mode == 'SCULPT_GPENCIL':
|
||||
settings = ts.gpencil_sculpt_paint
|
||||
settings = tool_settings.gpencil_sculpt_paint
|
||||
elif context.mode == 'WEIGHT_GPENCIL':
|
||||
settings = ts.gpencil_weight_paint
|
||||
settings = tool_settings.gpencil_weight_paint
|
||||
elif context.mode == 'VERTEX_GPENCIL':
|
||||
settings = ts.gpencil_vertex_paint
|
||||
settings = tool_settings.gpencil_vertex_paint
|
||||
|
||||
if settings:
|
||||
brush = settings.brush
|
||||
|
@ -585,9 +588,9 @@ class GreasePencilVertexcolorPanel:
|
|||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
ts = context.scene.tool_settings
|
||||
tool_settings = context.scene.tool_settings
|
||||
is_vertex = context.mode == 'VERTEX_GPENCIL'
|
||||
gpencil_paint = ts.gpencil_vertex_paint if is_vertex else ts.gpencil_paint
|
||||
gpencil_paint = tool_settings.gpencil_vertex_paint if is_vertex else tool_settings.gpencil_paint
|
||||
brush = gpencil_paint.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
tool = brush.gpencil_vertex_tool if is_vertex else brush.gpencil_tool
|
||||
|
@ -855,30 +858,30 @@ class GreasePencilFlipTintColors(Operator):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ts = context.tool_settings
|
||||
tool_settings = context.tool_settings
|
||||
settings = None
|
||||
if context.mode == 'PAINT_GPENCIL':
|
||||
settings = ts.gpencil_paint
|
||||
settings = tool_settings.gpencil_paint
|
||||
if context.mode == 'SCULPT_GPENCIL':
|
||||
settings = ts.gpencil_sculpt_paint
|
||||
settings = tool_settings.gpencil_sculpt_paint
|
||||
elif context.mode == 'WEIGHT_GPENCIL':
|
||||
settings = ts.gpencil_weight_paint
|
||||
settings = tool_settings.gpencil_weight_paint
|
||||
elif context.mode == 'VERTEX_GPENCIL':
|
||||
settings = ts.gpencil_vertex_paint
|
||||
settings = tool_settings.gpencil_vertex_paint
|
||||
|
||||
return settings and settings.brush
|
||||
|
||||
def execute(self, context):
|
||||
ts = context.tool_settings
|
||||
tool_settings = context.tool_settings
|
||||
settings = None
|
||||
if context.mode == 'PAINT_GPENCIL':
|
||||
settings = ts.gpencil_paint
|
||||
settings = tool_settings.gpencil_paint
|
||||
if context.mode == 'SCULPT_GPENCIL':
|
||||
settings = ts.gpencil_sculpt_paint
|
||||
settings = tool_settings.gpencil_sculpt_paint
|
||||
elif context.mode == 'WEIGHT_GPENCIL':
|
||||
settings = ts.gpencil_weight_paint
|
||||
settings = tool_settings.gpencil_weight_paint
|
||||
elif context.mode == 'VERTEX_GPENCIL':
|
||||
settings = ts.gpencil_vertex_paint
|
||||
settings = tool_settings.gpencil_vertex_paint
|
||||
|
||||
brush = settings.brush
|
||||
color = brush.color
|
||||
|
|
|
@ -378,7 +378,9 @@ class SmoothStrokePanel(BrushPanel):
|
|||
settings = self.paint_settings(context)
|
||||
brush = settings.brush
|
||||
|
||||
self.layout.prop(brush, "use_smooth_stroke", text="")
|
||||
self.layout.use_property_split = False
|
||||
self.layout.prop(brush, "use_smooth_stroke",
|
||||
text=self.bl_label if self.is_popover else "")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -472,8 +474,8 @@ class DisplayPanel(BrushPanel):
|
|||
|
||||
if self.is_popover:
|
||||
row = layout.row(align=True)
|
||||
row.prop(settings, "show_brush", text="")
|
||||
row.label(text="Display Cursor")
|
||||
row.use_property_split = False
|
||||
row.prop(settings, "show_brush", text="Display Cursor")
|
||||
|
||||
col = layout.column()
|
||||
col.active = brush.brush_capabilities.has_overlay and settings.show_brush
|
||||
|
|
|
@ -328,7 +328,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel):
|
|||
col = layout.column()
|
||||
col.prop(part, "emit_from")
|
||||
col.prop(part, "use_modifier_stack")
|
||||
if part.emit_from == 'FACE' or part.emit_from == 'VOLUME':
|
||||
if part.emit_from in {'FACE', 'VOLUME'}:
|
||||
col.prop(part, "distribution")
|
||||
|
||||
if part.emit_from == 'VERT':
|
||||
|
@ -340,7 +340,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel):
|
|||
col.prop(part, "use_emit_random", text="Random Order")
|
||||
col.prop(part, "use_even_distribution")
|
||||
|
||||
if part.emit_from == 'FACE' or part.emit_from == 'VOLUME':
|
||||
if part.emit_from in {'FACE', 'VOLUME'}:
|
||||
|
||||
if part.distribution == 'JIT':
|
||||
col.prop(part, "userjit", text="Particles/Face")
|
||||
|
|
|
@ -37,6 +37,7 @@ def physics_add(layout, md, name, type, typeicon, toggles):
|
|||
text_ctxt=i18n_contexts.default,
|
||||
icon=typeicon,
|
||||
).type = type
|
||||
return None
|
||||
|
||||
|
||||
def physics_add_special(layout, data, name, addop, removeop, typeicon):
|
||||
|
|
|
@ -82,8 +82,7 @@ class PhysicButtonsPanel:
|
|||
|
||||
md = context.fluid
|
||||
flow = md.flow_settings
|
||||
if (flow.flow_behavior == 'OUTFLOW'):
|
||||
return True
|
||||
return (flow.flow_behavior == 'OUTFLOW')
|
||||
|
||||
@staticmethod
|
||||
def poll_fluid_flow_liquid(context):
|
||||
|
@ -92,8 +91,7 @@ class PhysicButtonsPanel:
|
|||
|
||||
md = context.fluid
|
||||
flow = md.flow_settings
|
||||
if (flow.flow_type == 'LIQUID'):
|
||||
return True
|
||||
return (flow.flow_type == 'LIQUID')
|
||||
|
||||
|
||||
class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel):
|
||||
|
|
|
@ -76,31 +76,6 @@ class VIEWLAYER_PT_eevee_layer_passes_data(ViewLayerButtonsPanel, Panel):
|
|||
col.prop(view_layer, "use_pass_normal")
|
||||
|
||||
|
||||
class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Data"
|
||||
bl_parent_id = "VIEWLAYER_PT_layer_passes"
|
||||
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
|
||||
col = layout.column()
|
||||
col.prop(view_layer, "use_pass_combined")
|
||||
col.prop(view_layer, "use_pass_z")
|
||||
col.prop(view_layer, "use_pass_mist")
|
||||
col.prop(view_layer, "use_pass_normal")
|
||||
col.prop(view_layer, "use_pass_position")
|
||||
sub = col.column()
|
||||
sub.active = not scene.eevee.use_motion_blur
|
||||
sub.prop(view_layer, "use_pass_vector")
|
||||
|
||||
|
||||
class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Data"
|
||||
bl_parent_id = "VIEWLAYER_PT_layer_passes"
|
||||
|
|
|
@ -1079,10 +1079,11 @@ class CLIP_PT_2d_cursor(Panel):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
sc = context.space_data
|
||||
if not CLIP_PT_clip_view_panel.poll(context):
|
||||
return False
|
||||
|
||||
if CLIP_PT_clip_view_panel.poll(context):
|
||||
return sc.pivot_point == 'CURSOR' or sc.mode == 'MASK'
|
||||
sc = context.space_data
|
||||
return sc.pivot_point == 'CURSOR' or sc.mode == 'MASK'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -1732,13 +1733,13 @@ class CLIP_MT_marker_pie(Menu):
|
|||
layout = self.layout
|
||||
pie = layout.menu_pie()
|
||||
# Use Location Tracking
|
||||
prop = pie.operator("wm.context_set_enum", text="Location")
|
||||
prop.data_path = "space_data.clip.tracking.tracks.active.motion_model"
|
||||
prop.value = "Loc"
|
||||
props = pie.operator("wm.context_set_enum", text="Location")
|
||||
props.data_path = "space_data.clip.tracking.tracks.active.motion_model"
|
||||
props.value = "Loc"
|
||||
# Use Affine Tracking
|
||||
prop = pie.operator("wm.context_set_enum", text="Affine")
|
||||
prop.data_path = "space_data.clip.tracking.tracks.active.motion_model"
|
||||
prop.value = "Affine"
|
||||
props = pie.operator("wm.context_set_enum", text="Affine")
|
||||
props.data_path = "space_data.clip.tracking.tracks.active.motion_model"
|
||||
props.value = "Affine"
|
||||
# Copy Settings From Active To Selected
|
||||
pie.operator("clip.track_settings_to_track", icon='COPYDOWN')
|
||||
# Make Settings Default
|
||||
|
@ -1749,13 +1750,13 @@ class CLIP_MT_marker_pie(Menu):
|
|||
# Use Brute Force
|
||||
pie.prop(track_active, "use_brute", text="Use Brute Force")
|
||||
# Match Keyframe
|
||||
prop = pie.operator("wm.context_set_enum", text="Match Previous", icon='KEYFRAME_HLT')
|
||||
prop.data_path = "space_data.clip.tracking.tracks.active.pattern_match"
|
||||
prop.value = 'PREV_FRAME'
|
||||
props = pie.operator("wm.context_set_enum", text="Match Previous", icon='KEYFRAME_HLT')
|
||||
props.data_path = "space_data.clip.tracking.tracks.active.pattern_match"
|
||||
props.value = 'PREV_FRAME'
|
||||
# Match Previous Frame
|
||||
prop = pie.operator("wm.context_set_enum", text="Match Keyframe", icon='KEYFRAME')
|
||||
prop.data_path = "space_data.clip.tracking.tracks.active.pattern_match"
|
||||
prop.value = 'KEYFRAME'
|
||||
props = pie.operator("wm.context_set_enum", text="Match Keyframe", icon='KEYFRAME')
|
||||
props.data_path = "space_data.clip.tracking.tracks.active.pattern_match"
|
||||
props.value = 'KEYFRAME'
|
||||
|
||||
|
||||
class CLIP_MT_tracking_pie(Menu):
|
||||
|
@ -1773,13 +1774,13 @@ class CLIP_MT_tracking_pie(Menu):
|
|||
|
||||
pie = layout.menu_pie()
|
||||
# Track Backwards
|
||||
prop = pie.operator("clip.track_markers", icon='TRACKING_BACKWARDS')
|
||||
prop.backwards = True
|
||||
prop.sequence = True
|
||||
props = pie.operator("clip.track_markers", icon='TRACKING_BACKWARDS')
|
||||
props.backwards = True
|
||||
props.sequence = True
|
||||
# Track Forwards
|
||||
prop = pie.operator("clip.track_markers", icon='TRACKING_FORWARDS')
|
||||
prop.backwards = False
|
||||
prop.sequence = True
|
||||
props = pie.operator("clip.track_markers", icon='TRACKING_FORWARDS')
|
||||
props.backwards = False
|
||||
props.sequence = True
|
||||
# Disable Marker
|
||||
pie.operator("clip.disable_markers", icon='HIDE_OFF').action = 'TOGGLE'
|
||||
# Detect Features
|
||||
|
@ -1831,11 +1832,11 @@ class CLIP_MT_solving_pie(Menu):
|
|||
icon='KEYFRAME',
|
||||
).keyframe = 'KEYFRAME_B'
|
||||
# Clean Tracks
|
||||
prop = pie.operator("clip.clean_tracks", icon='X')
|
||||
props = pie.operator("clip.clean_tracks", icon='X')
|
||||
props.frames = 15
|
||||
props.error = 2
|
||||
# Filter Tracks
|
||||
pie.operator("clip.filter_tracks", icon='FILTER')
|
||||
prop.frames = 15
|
||||
prop.error = 2
|
||||
|
||||
|
||||
class CLIP_MT_reconstruction_pie(Menu):
|
||||
|
|
|
@ -7,8 +7,7 @@ class CONSOLE_HT_header(Header):
|
|||
bl_space_type = 'CONSOLE'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout.row()
|
||||
|
||||
layout = self.layout
|
||||
layout.template_header()
|
||||
|
||||
CONSOLE_MT_editor_menus.draw_collapsible(context, layout)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from bpy.types import Header, Menu, Panel
|
||||
from bl_ui_utils.layout import operator_context
|
||||
from bl_ui.space_dopesheet import (
|
||||
DopesheetFilterPopoverBase,
|
||||
dopesheet_filter,
|
||||
|
@ -241,6 +240,8 @@ class GRAPH_MT_key(Menu):
|
|||
bl_label = "Key"
|
||||
|
||||
def draw(self, _context):
|
||||
from bl_ui_utils.layout import operator_context
|
||||
|
||||
layout = self.layout
|
||||
|
||||
layout.menu("GRAPH_MT_key_transform", text="Transform")
|
||||
|
|
|
@ -4,7 +4,6 @@ from bpy.types import Header, Menu, Panel
|
|||
|
||||
from bpy.app.translations import (
|
||||
contexts as i18n_contexts,
|
||||
pgettext_iface as iface_,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -135,8 +135,6 @@ class SEQUENCER_HT_tool_header(Header):
|
|||
# TODO: options popover.
|
||||
|
||||
def draw_tool_settings(self, context):
|
||||
pass
|
||||
|
||||
layout = self.layout
|
||||
|
||||
# Active Tool
|
||||
|
@ -621,17 +619,17 @@ class SEQUENCER_MT_change(Menu):
|
|||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
layout.operator_menu_enum("sequencer.change_effect_input", "swap")
|
||||
layout.operator_menu_enum("sequencer.change_effect_type", "type")
|
||||
prop = layout.operator("sequencer.change_path", text="Path/Files")
|
||||
props = layout.operator("sequencer.change_path", text="Path/Files")
|
||||
|
||||
if strip:
|
||||
strip_type = strip.type
|
||||
|
||||
if strip_type == 'IMAGE':
|
||||
prop.filter_image = True
|
||||
props.filter_image = True
|
||||
elif strip_type == 'MOVIE':
|
||||
prop.filter_movie = True
|
||||
props.filter_movie = True
|
||||
elif strip_type == 'SOUND':
|
||||
prop.filter_sound = True
|
||||
props.filter_sound = True
|
||||
|
||||
|
||||
class SEQUENCER_MT_navigation(Menu):
|
||||
|
@ -865,18 +863,18 @@ class SEQUENCER_MT_strip_input(Menu):
|
|||
|
||||
layout.operator("sequencer.reload", text="Reload Strips")
|
||||
layout.operator("sequencer.reload", text="Reload Strips and Adjust Length").adjust_length = True
|
||||
prop = layout.operator("sequencer.change_path", text="Change Path/Files")
|
||||
props = layout.operator("sequencer.change_path", text="Change Path/Files")
|
||||
layout.operator("sequencer.swap_data", text="Swap Data")
|
||||
|
||||
if strip:
|
||||
strip_type = strip.type
|
||||
|
||||
if strip_type == 'IMAGE':
|
||||
prop.filter_image = True
|
||||
props.filter_image = True
|
||||
elif strip_type == 'MOVIE':
|
||||
prop.filter_movie = True
|
||||
props.filter_movie = True
|
||||
elif strip_type == 'SOUND':
|
||||
prop.filter_sound = True
|
||||
props.filter_sound = True
|
||||
|
||||
|
||||
class SEQUENCER_MT_strip_lock_mute(Menu):
|
||||
|
@ -2006,7 +2004,7 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel):
|
|||
split.prop(strip, "pan", text="")
|
||||
split.enabled = pan_enabled
|
||||
|
||||
if audio_channels != 'MONO' and audio_channels != 'STEREO':
|
||||
if audio_channels not in {'MONO', 'STEREO'}:
|
||||
split = col.split(factor=0.4)
|
||||
split.alignment = 'RIGHT'
|
||||
split.label(text="Pan Angle")
|
||||
|
|
|
@ -451,6 +451,7 @@ class _defs_view3d_add:
|
|||
for item in km.keymap_items:
|
||||
if item.propvalue == propvalue:
|
||||
return item
|
||||
return None
|
||||
|
||||
if km is not None:
|
||||
kmi_snap = keymap_item_from_propvalue('SNAP_ON')
|
||||
|
@ -2094,13 +2095,13 @@ class _defs_gpencil_paint:
|
|||
|
||||
class _defs_gpencil_edit:
|
||||
def is_segment(context):
|
||||
ts = context.scene.tool_settings
|
||||
tool_settings = context.scene.tool_settings
|
||||
if context.mode == 'EDIT_GPENCIL':
|
||||
return ts.gpencil_selectmode_edit == 'SEGMENT'
|
||||
return tool_settings.gpencil_selectmode_edit == 'SEGMENT'
|
||||
elif context.mode == 'SCULPT_GPENCIL':
|
||||
return ts.use_gpencil_select_mask_segment
|
||||
return tool_settings.use_gpencil_select_mask_segment
|
||||
elif context.mode == 'VERTEX_GPENCIL':
|
||||
return ts.use_gpencil_vertex_select_mask_segment
|
||||
return tool_settings.use_gpencil_vertex_select_mask_segment
|
||||
else:
|
||||
return False
|
||||
|
||||
|
@ -2283,10 +2284,15 @@ class _defs_gpencil_sculpt:
|
|||
if context is None:
|
||||
return True
|
||||
ob = context.active_object
|
||||
ts = context.scene.tool_settings
|
||||
return ob and ob.type == 'GPENCIL' and (ts.use_gpencil_select_mask_point or
|
||||
ts.use_gpencil_select_mask_stroke or
|
||||
ts.use_gpencil_select_mask_segment)
|
||||
tool_settings = context.scene.tool_settings
|
||||
return (
|
||||
ob is not None and
|
||||
ob.type == 'GPENCIL' and (
|
||||
tool_settings.use_gpencil_select_mask_point or
|
||||
tool_settings.use_gpencil_select_mask_stroke or
|
||||
tool_settings.use_gpencil_select_mask_segment
|
||||
)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def generate_from_brushes(context):
|
||||
|
@ -2427,10 +2433,15 @@ class _defs_gpencil_vertex:
|
|||
if context is None:
|
||||
return True
|
||||
ob = context.active_object
|
||||
ts = context.scene.tool_settings
|
||||
return ob and ob.type == 'GPENCIL' and (ts.use_gpencil_vertex_select_mask_point or
|
||||
ts.use_gpencil_vertex_select_mask_stroke or
|
||||
ts.use_gpencil_vertex_select_mask_segment)
|
||||
tool_settings = context.scene.tool_settings
|
||||
return (
|
||||
ob is not None and
|
||||
ob.type == 'GPENCIL' and (
|
||||
tool_settings.use_gpencil_vertex_select_mask_point or
|
||||
tool_settings.use_gpencil_vertex_select_mask_stroke or
|
||||
tool_settings.use_gpencil_vertex_select_mask_segment
|
||||
)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def generate_from_brushes(context):
|
||||
|
@ -2652,7 +2663,6 @@ class _defs_sequencer_select:
|
|||
row = layout.row()
|
||||
row.use_property_split = False
|
||||
row.prop(props, "mode", text="", expand=True, icon_only=True)
|
||||
pass
|
||||
return dict(
|
||||
idname="builtin.select_box",
|
||||
label="Select Box",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
import bpy
|
||||
from bpy.types import Header, Menu, Panel
|
||||
from bl_ui_utils.layout import operator_context
|
||||
|
||||
from bpy.app.translations import (
|
||||
pgettext_iface as iface_,
|
||||
|
@ -236,34 +235,34 @@ class TOPBAR_MT_file_cleanup(Menu):
|
|||
layout = self.layout
|
||||
layout.separator()
|
||||
|
||||
op_props = layout.operator("outliner.orphans_purge", text="Unused Data-Blocks")
|
||||
op_props.do_local_ids = True
|
||||
op_props.do_linked_ids = True
|
||||
op_props.do_recursive = False
|
||||
op_props = layout.operator("outliner.orphans_purge", text="Recursive Unused Data-Blocks")
|
||||
op_props.do_local_ids = True
|
||||
op_props.do_linked_ids = True
|
||||
op_props.do_recursive = True
|
||||
props = layout.operator("outliner.orphans_purge", text="Unused Data-Blocks")
|
||||
props.do_local_ids = True
|
||||
props.do_linked_ids = True
|
||||
props.do_recursive = False
|
||||
props = layout.operator("outliner.orphans_purge", text="Recursive Unused Data-Blocks")
|
||||
props.do_local_ids = True
|
||||
props.do_linked_ids = True
|
||||
props.do_recursive = True
|
||||
|
||||
layout.separator()
|
||||
op_props = layout.operator("outliner.orphans_purge", text="Unused Linked Data-Blocks")
|
||||
op_props.do_local_ids = False
|
||||
op_props.do_linked_ids = True
|
||||
op_props.do_recursive = False
|
||||
op_props = layout.operator("outliner.orphans_purge", text="Recursive Unused Linked Data-Blocks")
|
||||
op_props.do_local_ids = False
|
||||
op_props.do_linked_ids = True
|
||||
op_props.do_recursive = True
|
||||
props = layout.operator("outliner.orphans_purge", text="Unused Linked Data-Blocks")
|
||||
props.do_local_ids = False
|
||||
props.do_linked_ids = True
|
||||
props.do_recursive = False
|
||||
props = layout.operator("outliner.orphans_purge", text="Recursive Unused Linked Data-Blocks")
|
||||
props.do_local_ids = False
|
||||
props.do_linked_ids = True
|
||||
props.do_recursive = True
|
||||
|
||||
layout.separator()
|
||||
op_props = layout.operator("outliner.orphans_purge", text="Unused Local Data-Blocks")
|
||||
op_props.do_local_ids = True
|
||||
op_props.do_linked_ids = False
|
||||
op_props.do_recursive = False
|
||||
op_props = layout.operator("outliner.orphans_purge", text="Recursive Unused Local Data-Blocks")
|
||||
op_props.do_local_ids = True
|
||||
op_props.do_linked_ids = False
|
||||
op_props.do_recursive = True
|
||||
props = layout.operator("outliner.orphans_purge", text="Unused Local Data-Blocks")
|
||||
props.do_local_ids = True
|
||||
props.do_linked_ids = False
|
||||
props.do_recursive = False
|
||||
props = layout.operator("outliner.orphans_purge", text="Recursive Unused Local Data-Blocks")
|
||||
props.do_local_ids = True
|
||||
props.do_linked_ids = False
|
||||
props.do_recursive = True
|
||||
|
||||
|
||||
class TOPBAR_MT_file(Menu):
|
||||
|
@ -643,11 +642,10 @@ class TOPBAR_MT_window(Menu):
|
|||
|
||||
def draw(self, context):
|
||||
import sys
|
||||
from bl_ui_utils.layout import operator_context
|
||||
|
||||
layout = self.layout
|
||||
|
||||
operator_context_default = layout.operator_context
|
||||
|
||||
layout.operator("wm.window_new")
|
||||
layout.operator("wm.window_new_main")
|
||||
|
||||
|
|
|
@ -2205,12 +2205,12 @@ class StudioLightPanelMixin:
|
|||
|
||||
row.template_icon(layout.icon(studio_light), scale=3.0)
|
||||
col = row.column()
|
||||
op = col.operator("preferences.studiolight_uninstall", text="", icon='REMOVE')
|
||||
op.index = studio_light.index
|
||||
props = col.operator("preferences.studiolight_uninstall", text="", icon='REMOVE')
|
||||
props.index = studio_light.index
|
||||
|
||||
if studio_light.type == 'STUDIO':
|
||||
op = col.operator("preferences.studiolight_copy_settings", text="", icon='IMPORT')
|
||||
op.index = studio_light.index
|
||||
props = col.operator("preferences.studiolight_copy_settings", text="", icon='IMPORT')
|
||||
props.index = studio_light.index
|
||||
|
||||
box.label(text=studio_light.name)
|
||||
|
||||
|
@ -2247,9 +2247,9 @@ class USERPREF_PT_studiolight_lights(StudioLightPanel, StudioLightPanelMixin, Pa
|
|||
|
||||
def draw_header_preset(self, _context):
|
||||
layout = self.layout
|
||||
op = layout.operator("preferences.studiolight_install", icon='IMPORT', text="Install...")
|
||||
op.type = 'STUDIO'
|
||||
op.filter_glob = ".sl"
|
||||
props = layout.operator("preferences.studiolight_install", icon='IMPORT', text="Install...")
|
||||
props.type = 'STUDIO'
|
||||
props.filter_glob = ".sl"
|
||||
layout.separator()
|
||||
|
||||
def get_error_message(self):
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
import bpy
|
||||
from bl_ui_utils.layout import operator_context
|
||||
from bpy.types import (
|
||||
Header,
|
||||
Menu,
|
||||
|
@ -570,6 +569,8 @@ class _draw_tool_settings_context_mode:
|
|||
elif curves_tool == "SLIDE":
|
||||
layout.popover("VIEW3D_PT_tools_brush_falloff")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class VIEW3D_HT_header(Header):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
|
@ -928,7 +929,7 @@ class VIEW3D_MT_editor_menus(Menu):
|
|||
edit_object = context.edit_object
|
||||
gp_edit = obj and obj.mode in {'EDIT_GPENCIL', 'PAINT_GPENCIL', 'SCULPT_GPENCIL',
|
||||
'WEIGHT_GPENCIL', 'VERTEX_GPENCIL'}
|
||||
ts = context.scene.tool_settings
|
||||
tool_settings = context.scene.tool_settings
|
||||
|
||||
layout.menu("VIEW3D_MT_view")
|
||||
|
||||
|
@ -937,9 +938,9 @@ class VIEW3D_MT_editor_menus(Menu):
|
|||
if mode_string not in {'PAINT_GPENCIL', 'WEIGHT_GPENCIL'}:
|
||||
if (
|
||||
mode_string == 'SCULPT_GPENCIL' and
|
||||
(ts.use_gpencil_select_mask_point or
|
||||
ts.use_gpencil_select_mask_stroke or
|
||||
ts.use_gpencil_select_mask_segment)
|
||||
(tool_settings.use_gpencil_select_mask_point or
|
||||
tool_settings.use_gpencil_select_mask_stroke or
|
||||
tool_settings.use_gpencil_select_mask_segment)
|
||||
):
|
||||
layout.menu("VIEW3D_MT_select_gpencil")
|
||||
elif mode_string == 'EDIT_GPENCIL':
|
||||
|
@ -1443,8 +1444,6 @@ class VIEW3D_MT_select_object_more_less(Menu):
|
|||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("object.select_more", text="More")
|
||||
layout.operator("object.select_less", text="Less")
|
||||
|
||||
|
@ -1509,8 +1508,6 @@ class VIEW3D_MT_select_pose_more_less(Menu):
|
|||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
layout = self.layout
|
||||
|
||||
props = layout.operator("pose.select_hierarchy", text="Parent")
|
||||
props.extend = False
|
||||
props.direction = 'PARENT'
|
||||
|
@ -1619,6 +1616,7 @@ class VIEW3D_MT_edit_mesh_select_by_trait(Menu):
|
|||
def draw(self, context):
|
||||
layout = self.layout
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
if tool_settings.mesh_select_mode[2] is False:
|
||||
layout.operator("mesh.select_non_manifold", text="Non Manifold")
|
||||
layout.operator("mesh.select_loose", text="Loose Geometry")
|
||||
|
@ -1855,8 +1853,6 @@ class VIEW3D_MT_edit_lattice_context_menu(Menu):
|
|||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
layout = self.layout
|
||||
|
||||
layout.menu("VIEW3D_MT_mirror")
|
||||
layout.operator_menu_enum("lattice.flip", "axis")
|
||||
layout.menu("VIEW3D_MT_snap")
|
||||
|
@ -2036,8 +2032,8 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
|
|||
layout.operator("paint.vert_select_all", text="None").action = 'DESELECT'
|
||||
layout.operator("paint.vert_select_all", text="Invert").action = 'INVERT'
|
||||
|
||||
layout.operator("paint.vert_select_more"),
|
||||
layout.operator("paint.vert_select_less"),
|
||||
layout.operator("paint.vert_select_more")
|
||||
layout.operator("paint.vert_select_less")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -2207,9 +2203,10 @@ class TOPBAR_MT_edit_curve_add(Menu):
|
|||
bl_translation_context = i18n_contexts.operator_default
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
is_surf = context.active_object.type == 'SURFACE'
|
||||
|
||||
layout = self.layout
|
||||
layout.operator_context = 'EXEC_REGION_WIN'
|
||||
|
||||
if is_surf:
|
||||
|
@ -2537,8 +2534,8 @@ class VIEW3D_MT_object_context_menu(Menu):
|
|||
bl_label = "Object Context Menu"
|
||||
|
||||
def draw(self, context):
|
||||
|
||||
layout = self.layout
|
||||
|
||||
view = context.space_data
|
||||
|
||||
obj = context.object
|
||||
|
@ -2766,6 +2763,7 @@ class VIEW3D_MT_object_apply(Menu):
|
|||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
# Need invoke for the popup confirming the multi-user data operation
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
|
||||
|
@ -2831,6 +2829,8 @@ class VIEW3D_MT_object_parent(Menu):
|
|||
bl_label = "Parent"
|
||||
|
||||
def draw(self, _context):
|
||||
from bl_ui_utils.layout import operator_context
|
||||
|
||||
layout = self.layout
|
||||
|
||||
layout.operator_enum("object.parent_set", "type")
|
||||
|
@ -3142,36 +3142,36 @@ class VIEW3D_MT_paint_weight_lock(Menu):
|
|||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
op = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All")
|
||||
op.action, op.mask = 'LOCK', 'ALL'
|
||||
props = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All")
|
||||
props.action, props.mask = 'LOCK', 'ALL'
|
||||
|
||||
op = layout.operator("object.vertex_group_lock", text="Lock Selected")
|
||||
op.action, op.mask = 'LOCK', 'SELECTED'
|
||||
props = layout.operator("object.vertex_group_lock", text="Lock Selected")
|
||||
props.action, props.mask = 'LOCK', 'SELECTED'
|
||||
|
||||
op = layout.operator("object.vertex_group_lock", text="Lock Unselected")
|
||||
op.action, op.mask = 'LOCK', 'UNSELECTED'
|
||||
props = layout.operator("object.vertex_group_lock", text="Lock Unselected")
|
||||
props.action, props.mask = 'LOCK', 'UNSELECTED'
|
||||
|
||||
op = layout.operator("object.vertex_group_lock", text="Lock Only Selected")
|
||||
op.action, op.mask = 'LOCK', 'INVERT_UNSELECTED'
|
||||
props = layout.operator("object.vertex_group_lock", text="Lock Only Selected")
|
||||
props.action, props.mask = 'LOCK', 'INVERT_UNSELECTED'
|
||||
|
||||
op = layout.operator("object.vertex_group_lock", text="Lock Only Unselected")
|
||||
op.action, op.mask = 'UNLOCK', 'INVERT_UNSELECTED'
|
||||
props = layout.operator("object.vertex_group_lock", text="Lock Only Unselected")
|
||||
props.action, props.mask = 'UNLOCK', 'INVERT_UNSELECTED'
|
||||
|
||||
layout.separator()
|
||||
|
||||
op = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All")
|
||||
op.action, op.mask = 'UNLOCK', 'ALL'
|
||||
props = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All")
|
||||
props.action, props.mask = 'UNLOCK', 'ALL'
|
||||
|
||||
op = layout.operator("object.vertex_group_lock", text="Unlock Selected")
|
||||
op.action, op.mask = 'UNLOCK', 'SELECTED'
|
||||
props = layout.operator("object.vertex_group_lock", text="Unlock Selected")
|
||||
props.action, props.mask = 'UNLOCK', 'SELECTED'
|
||||
|
||||
op = layout.operator("object.vertex_group_lock", text="Unlock Unselected")
|
||||
op.action, op.mask = 'UNLOCK', 'UNSELECTED'
|
||||
props = layout.operator("object.vertex_group_lock", text="Unlock Unselected")
|
||||
props.action, props.mask = 'UNLOCK', 'UNSELECTED'
|
||||
|
||||
layout.separator()
|
||||
|
||||
op = layout.operator("object.vertex_group_lock", icon='ARROW_LEFTRIGHT', text="Invert Locks")
|
||||
op.action, op.mask = 'INVERT', 'ALL'
|
||||
props = layout.operator("object.vertex_group_lock", icon='ARROW_LEFTRIGHT', text="Invert Locks")
|
||||
props.action, props.mask = 'INVERT', 'ALL'
|
||||
|
||||
|
||||
class VIEW3D_MT_paint_weight(Menu):
|
||||
|
@ -3416,14 +3416,14 @@ class VIEW3D_MT_face_sets(Menu):
|
|||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
op = layout.operator("sculpt.face_sets_create", text="Face Set from Masked")
|
||||
op.mode = 'MASKED'
|
||||
props = layout.operator("sculpt.face_sets_create", text="Face Set from Masked")
|
||||
props.mode = 'MASKED'
|
||||
|
||||
op = layout.operator("sculpt.face_sets_create", text="Face Set from Visible")
|
||||
op.mode = 'VISIBLE'
|
||||
props = layout.operator("sculpt.face_sets_create", text="Face Set from Visible")
|
||||
props.mode = 'VISIBLE'
|
||||
|
||||
op = layout.operator("sculpt.face_sets_create", text="Face Set from Edit Mode Selection")
|
||||
op.mode = 'SELECTION'
|
||||
props = layout.operator("sculpt.face_sets_create", text="Face Set from Edit Mode Selection")
|
||||
props.mode = 'SELECTION'
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -3431,11 +3431,11 @@ class VIEW3D_MT_face_sets(Menu):
|
|||
|
||||
layout.separator()
|
||||
|
||||
op = layout.operator("sculpt.face_set_edit", text="Grow Face Set")
|
||||
op.mode = 'GROW'
|
||||
props = layout.operator("sculpt.face_set_edit", text="Grow Face Set")
|
||||
props.mode = 'GROW'
|
||||
|
||||
op = layout.operator("sculpt.face_set_edit", text="Shrink Face Set")
|
||||
op.mode = 'SHRINK'
|
||||
props = layout.operator("sculpt.face_set_edit", text="Shrink Face Set")
|
||||
props.mode = 'SHRINK'
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -3453,18 +3453,18 @@ class VIEW3D_MT_face_sets(Menu):
|
|||
|
||||
layout.separator()
|
||||
|
||||
op = layout.operator("mesh.face_set_extract", text="Extract Face Set")
|
||||
props = layout.operator("mesh.face_set_extract", text="Extract Face Set")
|
||||
|
||||
layout.separator()
|
||||
|
||||
op = layout.operator("sculpt.face_set_change_visibility", text="Invert Visible Face Sets")
|
||||
op.mode = 'INVERT'
|
||||
props = layout.operator("sculpt.face_set_change_visibility", text="Invert Visible Face Sets")
|
||||
props.mode = 'INVERT'
|
||||
|
||||
op = layout.operator("sculpt.reveal_all", text="Show All Face Sets")
|
||||
props = layout.operator("sculpt.reveal_all", text="Show All Face Sets")
|
||||
|
||||
layout.separator()
|
||||
|
||||
op = layout.operator("sculpt.face_sets_randomize_colors", text="Randomize Colors")
|
||||
props = layout.operator("sculpt.face_sets_randomize_colors", text="Randomize Colors")
|
||||
|
||||
|
||||
class VIEW3D_MT_sculpt_set_pivot(Menu):
|
||||
|
@ -3495,32 +3495,32 @@ class VIEW3D_MT_face_sets_init(Menu):
|
|||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
op = layout.operator("sculpt.face_sets_init", text="By Loose Parts")
|
||||
op.mode = 'LOOSE_PARTS'
|
||||
props = layout.operator("sculpt.face_sets_init", text="By Loose Parts")
|
||||
props.mode = 'LOOSE_PARTS'
|
||||
|
||||
op = layout.operator("sculpt.face_sets_init", text="By Face Set Boundaries")
|
||||
op.mode = 'FACE_SET_BOUNDARIES'
|
||||
props = layout.operator("sculpt.face_sets_init", text="By Face Set Boundaries")
|
||||
props.mode = 'FACE_SET_BOUNDARIES'
|
||||
|
||||
op = layout.operator("sculpt.face_sets_init", text="By Materials")
|
||||
op.mode = 'MATERIALS'
|
||||
props = layout.operator("sculpt.face_sets_init", text="By Materials")
|
||||
props.mode = 'MATERIALS'
|
||||
|
||||
op = layout.operator("sculpt.face_sets_init", text="By Normals")
|
||||
op.mode = 'NORMALS'
|
||||
props = layout.operator("sculpt.face_sets_init", text="By Normals")
|
||||
props.mode = 'NORMALS'
|
||||
|
||||
op = layout.operator("sculpt.face_sets_init", text="By UV Seams")
|
||||
op.mode = 'UV_SEAMS'
|
||||
props = layout.operator("sculpt.face_sets_init", text="By UV Seams")
|
||||
props.mode = 'UV_SEAMS'
|
||||
|
||||
op = layout.operator("sculpt.face_sets_init", text="By Edge Creases")
|
||||
op.mode = 'CREASES'
|
||||
props = layout.operator("sculpt.face_sets_init", text="By Edge Creases")
|
||||
props.mode = 'CREASES'
|
||||
|
||||
op = layout.operator("sculpt.face_sets_init", text="By Edge Bevel Weight")
|
||||
op.mode = 'BEVEL_WEIGHT'
|
||||
props = layout.operator("sculpt.face_sets_init", text="By Edge Bevel Weight")
|
||||
props.mode = 'BEVEL_WEIGHT'
|
||||
|
||||
op = layout.operator("sculpt.face_sets_init", text="By Sharp Edges")
|
||||
op.mode = 'SHARP_EDGES'
|
||||
props = layout.operator("sculpt.face_sets_init", text="By Sharp Edges")
|
||||
props.mode = 'SHARP_EDGES'
|
||||
|
||||
op = layout.operator("sculpt.face_sets_init", text="By Face Maps")
|
||||
op.mode = 'FACE_MAPS'
|
||||
props = layout.operator("sculpt.face_sets_init", text="By Face Maps")
|
||||
props.mode = 'FACE_MAPS'
|
||||
|
||||
|
||||
class VIEW3D_MT_random_mask(Menu):
|
||||
|
@ -3529,14 +3529,14 @@ class VIEW3D_MT_random_mask(Menu):
|
|||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
op = layout.operator("sculpt.mask_init", text="Per Vertex")
|
||||
op.mode = 'RANDOM_PER_VERTEX'
|
||||
props = layout.operator("sculpt.mask_init", text="Per Vertex")
|
||||
props.mode = 'RANDOM_PER_VERTEX'
|
||||
|
||||
op = layout.operator("sculpt.mask_init", text="Per Face Set")
|
||||
op.mode = 'RANDOM_PER_FACE_SET'
|
||||
props = layout.operator("sculpt.mask_init", text="Per Face Set")
|
||||
props.mode = 'RANDOM_PER_FACE_SET'
|
||||
|
||||
op = layout.operator("sculpt.mask_init", text="Per Loose Part")
|
||||
op.mode = 'RANDOM_PER_LOOSE_PART'
|
||||
props = layout.operator("sculpt.mask_init", text="Per Loose Part")
|
||||
props.mode = 'RANDOM_PER_LOOSE_PART'
|
||||
|
||||
|
||||
class VIEW3D_MT_particle(Menu):
|
||||
|
@ -4430,17 +4430,17 @@ class VIEW3D_MT_edit_mesh_normals_select_strength(Menu):
|
|||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
op = layout.operator("mesh.mod_weighted_strength", text="Weak")
|
||||
op.set = False
|
||||
op.face_strength = 'WEAK'
|
||||
props = layout.operator("mesh.mod_weighted_strength", text="Weak")
|
||||
props.set = False
|
||||
props.face_strength = 'WEAK'
|
||||
|
||||
op = layout.operator("mesh.mod_weighted_strength", text="Medium")
|
||||
op.set = False
|
||||
op.face_strength = 'MEDIUM'
|
||||
props = layout.operator("mesh.mod_weighted_strength", text="Medium")
|
||||
props.set = False
|
||||
props.face_strength = 'MEDIUM'
|
||||
|
||||
op = layout.operator("mesh.mod_weighted_strength", text="Strong")
|
||||
op.set = False
|
||||
op.face_strength = 'STRONG'
|
||||
props = layout.operator("mesh.mod_weighted_strength", text="Strong")
|
||||
props.set = False
|
||||
props.face_strength = 'STRONG'
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_normals_set_strength(Menu):
|
||||
|
@ -4449,17 +4449,17 @@ class VIEW3D_MT_edit_mesh_normals_set_strength(Menu):
|
|||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
op = layout.operator("mesh.mod_weighted_strength", text="Weak")
|
||||
op.set = True
|
||||
op.face_strength = 'WEAK'
|
||||
props = layout.operator("mesh.mod_weighted_strength", text="Weak")
|
||||
props.set = True
|
||||
props.face_strength = 'WEAK'
|
||||
|
||||
op = layout.operator("mesh.mod_weighted_strength", text="Medium")
|
||||
op.set = True
|
||||
op.face_strength = 'MEDIUM'
|
||||
props = layout.operator("mesh.mod_weighted_strength", text="Medium")
|
||||
props.set = True
|
||||
props.face_strength = 'MEDIUM'
|
||||
|
||||
op = layout.operator("mesh.mod_weighted_strength", text="Strong")
|
||||
op.set = True
|
||||
op.face_strength = 'STRONG'
|
||||
props = layout.operator("mesh.mod_weighted_strength", text="Strong")
|
||||
props.set = True
|
||||
props.face_strength = 'STRONG'
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_normals_average(Menu):
|
||||
|
@ -4865,8 +4865,8 @@ class VIEW3D_MT_edit_font_kerning(Menu):
|
|||
text = ob.data
|
||||
kerning = text.edit_format.kerning
|
||||
|
||||
layout.operator("font.change_spacing", text="Decrease Kerning").delta = -1
|
||||
layout.operator("font.change_spacing", text="Increase Kerning").delta = 1
|
||||
layout.operator("font.change_spacing", text="Decrease Kerning").delta = -1.0
|
||||
layout.operator("font.change_spacing", text="Increase Kerning").delta = 1.0
|
||||
layout.operator("font.change_spacing", text="Reset Kerning").delta = -kerning
|
||||
|
||||
|
||||
|
@ -5275,9 +5275,9 @@ class VIEW3D_MT_edit_gpencil_stroke(Menu):
|
|||
layout.separator()
|
||||
|
||||
# Convert
|
||||
op = layout.operator("gpencil.stroke_cyclical_set", text="Close")
|
||||
op.type = 'CLOSE'
|
||||
op.geometry = True
|
||||
props = layout.operator("gpencil.stroke_cyclical_set", text="Close")
|
||||
props.type = 'CLOSE'
|
||||
props.geometry = True
|
||||
layout.operator("gpencil.stroke_cyclical_set", text="Toggle Cyclic").type = 'TOGGLE'
|
||||
layout.operator_menu_enum("gpencil.stroke_caps_set", text="Toggle Caps", property="type")
|
||||
layout.operator("gpencil.stroke_flip", text="Switch Direction")
|
||||
|
@ -5568,25 +5568,25 @@ class VIEW3D_MT_sculpt_mask_edit_pie(Menu):
|
|||
layout = self.layout
|
||||
pie = layout.menu_pie()
|
||||
|
||||
op = pie.operator("paint.mask_flood_fill", text="Invert Mask")
|
||||
op.mode = 'INVERT'
|
||||
op = pie.operator("paint.mask_flood_fill", text="Clear Mask")
|
||||
op.mode = 'VALUE'
|
||||
op.value = 0.0
|
||||
op = pie.operator("sculpt.mask_filter", text="Smooth Mask")
|
||||
op.filter_type = 'SMOOTH'
|
||||
op = pie.operator("sculpt.mask_filter", text="Sharpen Mask")
|
||||
op.filter_type = 'SHARPEN'
|
||||
op = pie.operator("sculpt.mask_filter", text="Grow Mask")
|
||||
op.filter_type = 'GROW'
|
||||
op = pie.operator("sculpt.mask_filter", text="Shrink Mask")
|
||||
op.filter_type = 'SHRINK'
|
||||
op = pie.operator("sculpt.mask_filter", text="Increase Contrast")
|
||||
op.filter_type = 'CONTRAST_INCREASE'
|
||||
op.auto_iteration_count = False
|
||||
op = pie.operator("sculpt.mask_filter", text="Decrease Contrast")
|
||||
op.filter_type = 'CONTRAST_DECREASE'
|
||||
op.auto_iteration_count = False
|
||||
props = pie.operator("paint.mask_flood_fill", text="Invert Mask")
|
||||
props.mode = 'INVERT'
|
||||
props = pie.operator("paint.mask_flood_fill", text="Clear Mask")
|
||||
props.mode = 'VALUE'
|
||||
props.value = 0.0
|
||||
props = pie.operator("sculpt.mask_filter", text="Smooth Mask")
|
||||
props.filter_type = 'SMOOTH'
|
||||
props = pie.operator("sculpt.mask_filter", text="Sharpen Mask")
|
||||
props.filter_type = 'SHARPEN'
|
||||
props = pie.operator("sculpt.mask_filter", text="Grow Mask")
|
||||
props.filter_type = 'GROW'
|
||||
props = pie.operator("sculpt.mask_filter", text="Shrink Mask")
|
||||
props.filter_type = 'SHRINK'
|
||||
props = pie.operator("sculpt.mask_filter", text="Increase Contrast")
|
||||
props.filter_type = 'CONTRAST_INCREASE'
|
||||
props.auto_iteration_count = False
|
||||
props = pie.operator("sculpt.mask_filter", text="Decrease Contrast")
|
||||
props.filter_type = 'CONTRAST_DECREASE'
|
||||
props.auto_iteration_count = False
|
||||
|
||||
|
||||
class VIEW3D_MT_sculpt_automasking_pie(Menu):
|
||||
|
@ -5633,16 +5633,16 @@ class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu):
|
|||
layout = self.layout
|
||||
pie = layout.menu_pie()
|
||||
|
||||
op = pie.operator("sculpt.face_sets_create", text="Face Set from Masked")
|
||||
op.mode = 'MASKED'
|
||||
props = pie.operator("sculpt.face_sets_create", text="Face Set from Masked")
|
||||
props.mode = 'MASKED'
|
||||
|
||||
op = pie.operator("sculpt.face_sets_create", text="Face Set from Visible")
|
||||
op.mode = 'VISIBLE'
|
||||
props = pie.operator("sculpt.face_sets_create", text="Face Set from Visible")
|
||||
props.mode = 'VISIBLE'
|
||||
|
||||
op = pie.operator("sculpt.face_set_change_visibility", text="Invert Visible")
|
||||
op.mode = 'INVERT'
|
||||
props = pie.operator("sculpt.face_set_change_visibility", text="Invert Visible")
|
||||
props.mode = 'INVERT'
|
||||
|
||||
op = pie.operator("sculpt.reveal_all", text="Show All")
|
||||
props = pie.operator("sculpt.reveal_all", text="Show All")
|
||||
|
||||
|
||||
class VIEW3D_MT_wpaint_vgroup_lock_pie(Menu):
|
||||
|
@ -5653,29 +5653,29 @@ class VIEW3D_MT_wpaint_vgroup_lock_pie(Menu):
|
|||
pie = layout.menu_pie()
|
||||
|
||||
# 1: Left
|
||||
op = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All")
|
||||
op.action, op.mask = 'LOCK', 'ALL'
|
||||
props = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All")
|
||||
props.action, props.mask = 'LOCK', 'ALL'
|
||||
# 2: Right
|
||||
op = pie.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All")
|
||||
op.action, op.mask = 'UNLOCK', 'ALL'
|
||||
props = pie.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All")
|
||||
props.action, props.mask = 'UNLOCK', 'ALL'
|
||||
# 3: Down
|
||||
op = pie.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock Selected")
|
||||
op.action, op.mask = 'UNLOCK', 'SELECTED'
|
||||
props = pie.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock Selected")
|
||||
props.action, props.mask = 'UNLOCK', 'SELECTED'
|
||||
# 4: Up
|
||||
op = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Selected")
|
||||
op.action, op.mask = 'LOCK', 'SELECTED'
|
||||
props = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Selected")
|
||||
props.action, props.mask = 'LOCK', 'SELECTED'
|
||||
# 5: Up/Left
|
||||
op = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Unselected")
|
||||
op.action, op.mask = 'LOCK', 'UNSELECTED'
|
||||
props = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Unselected")
|
||||
props.action, props.mask = 'LOCK', 'UNSELECTED'
|
||||
# 6: Up/Right
|
||||
op = pie.operator("object.vertex_group_lock", text="Lock Only Selected")
|
||||
op.action, op.mask = 'LOCK', 'INVERT_UNSELECTED'
|
||||
props = pie.operator("object.vertex_group_lock", text="Lock Only Selected")
|
||||
props.action, props.mask = 'LOCK', 'INVERT_UNSELECTED'
|
||||
# 7: Down/Left
|
||||
op = pie.operator("object.vertex_group_lock", text="Lock Only Unselected")
|
||||
op.action, op.mask = 'UNLOCK', 'INVERT_UNSELECTED'
|
||||
props = pie.operator("object.vertex_group_lock", text="Lock Only Unselected")
|
||||
props.action, props.mask = 'UNLOCK', 'INVERT_UNSELECTED'
|
||||
# 8: Down/Right
|
||||
op = pie.operator("object.vertex_group_lock", text="Invert Locks")
|
||||
op.action, op.mask = 'INVERT', 'ALL'
|
||||
props = pie.operator("object.vertex_group_lock", text="Invert Locks")
|
||||
props.action, props.mask = 'INVERT', 'ALL'
|
||||
|
||||
|
||||
# ********** Panel **********
|
||||
|
@ -6812,7 +6812,6 @@ class VIEW3D_PT_overlay_sculpt(Panel):
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
view = context.space_data
|
||||
overlay = view.overlay
|
||||
|
@ -6843,8 +6842,6 @@ class VIEW3D_PT_overlay_sculpt_curves(Panel):
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
tool_settings = context.tool_settings
|
||||
sculpt = tool_settings.sculpt
|
||||
|
||||
view = context.space_data
|
||||
overlay = view.overlay
|
||||
|
@ -6978,6 +6975,7 @@ class VIEW3D_PT_overlay_weight_paint(Panel):
|
|||
view = context.space_data
|
||||
overlay = view.overlay
|
||||
display_all = overlay.show_overlays
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
col = layout.column()
|
||||
col.active = display_all
|
||||
|
@ -6986,7 +6984,7 @@ class VIEW3D_PT_overlay_weight_paint(Panel):
|
|||
row = col.split(factor=0.33)
|
||||
row.label(text="Zero Weights")
|
||||
sub = row.row()
|
||||
sub.prop(context.tool_settings, "vertex_group_user", expand=True)
|
||||
sub.prop(tool_settings, "vertex_group_user", expand=True)
|
||||
|
||||
col.prop(overlay, "show_wpaint_contours")
|
||||
col.prop(overlay, "show_paint_wire")
|
||||
|
@ -7157,11 +7155,13 @@ class VIEW3D_PT_gpencil_lock(Panel):
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
layout.label(text="Drawing Plane")
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
col.prop(context.tool_settings.gpencil_sculpt, "lock_axis", expand=True)
|
||||
col.prop(tool_settings.gpencil_sculpt, "lock_axis", expand=True)
|
||||
|
||||
|
||||
class VIEW3D_PT_gpencil_guide(Panel):
|
||||
|
@ -7427,10 +7427,12 @@ class VIEW3D_PT_gpencil_multi_frame(Panel):
|
|||
bl_label = "Multi Frame"
|
||||
|
||||
def draw(self, context):
|
||||
gpd = context.gpencil_data
|
||||
settings = context.tool_settings.gpencil_sculpt
|
||||
|
||||
layout = self.layout
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
gpd = context.gpencil_data
|
||||
settings = tool_settings.gpencil_sculpt
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(settings, "use_multiframe_falloff")
|
||||
|
||||
|
@ -7460,12 +7462,12 @@ class VIEW3D_MT_gpencil_edit_context_menu(Menu):
|
|||
bl_label = ""
|
||||
|
||||
def draw(self, context):
|
||||
|
||||
is_point_mode = context.tool_settings.gpencil_selectmode_edit == 'POINT'
|
||||
is_stroke_mode = context.tool_settings.gpencil_selectmode_edit == 'STROKE'
|
||||
is_segment_mode = context.tool_settings.gpencil_selectmode_edit == 'SEGMENT'
|
||||
|
||||
layout = self.layout
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
is_point_mode = tool_settings.gpencil_selectmode_edit == 'POINT'
|
||||
is_stroke_mode = tool_settings.gpencil_selectmode_edit == 'STROKE'
|
||||
is_segment_mode = tool_settings.gpencil_selectmode_edit == 'SEGMENT'
|
||||
|
||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
|
||||
|
@ -7607,8 +7609,8 @@ class VIEW3D_PT_gpencil_sculpt_automasking(Panel):
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tool_settings = context.scene.tool_settings
|
||||
|
||||
layout.label(text="Auto-masking")
|
||||
|
||||
col = layout.column(align=True)
|
||||
|
@ -7627,11 +7629,11 @@ class VIEW3D_PT_gpencil_sculpt_context_menu(Panel):
|
|||
bl_ui_units_x = 12
|
||||
|
||||
def draw(self, context):
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_sculpt_paint
|
||||
brush = settings.brush
|
||||
|
||||
layout = self.layout
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
settings = tool_settings.gpencil_sculpt_paint
|
||||
brush = settings.brush
|
||||
|
||||
layout.prop(brush, "size", slider=True)
|
||||
layout.prop(brush, "strength")
|
||||
|
@ -7647,8 +7649,8 @@ class VIEW3D_PT_gpencil_weight_context_menu(Panel):
|
|||
bl_ui_units_x = 12
|
||||
|
||||
def draw(self, context):
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_weight_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_weight_paint
|
||||
brush = settings.brush
|
||||
|
||||
layout = self.layout
|
||||
|
@ -7668,12 +7670,12 @@ class VIEW3D_PT_gpencil_draw_context_menu(Panel):
|
|||
bl_ui_units_x = 12
|
||||
|
||||
def draw(self, context):
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_paint
|
||||
layout = self.layout
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_paint
|
||||
brush = settings.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
|
||||
layout = self.layout
|
||||
is_pin_vertex = gp_settings.brush_draw_mode == 'VERTEXCOLOR'
|
||||
is_vertex = settings.color_mode == 'VERTEXCOLOR' or brush.gpencil_tool == 'TINT' or is_pin_vertex
|
||||
|
||||
|
@ -7707,8 +7709,8 @@ class VIEW3D_PT_gpencil_vertex_context_menu(Panel):
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_vertex_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_vertex_paint
|
||||
brush = settings.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
|
||||
|
|
|
@ -61,17 +61,17 @@ class VIEW3D_MT_brush_gpencil_context_menu(Menu):
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ts = context.tool_settings
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
settings = None
|
||||
if context.mode == 'PAINT_GPENCIL':
|
||||
settings = ts.gpencil_paint
|
||||
settings = tool_settings.gpencil_paint
|
||||
if context.mode == 'SCULPT_GPENCIL':
|
||||
settings = ts.gpencil_sculpt_paint
|
||||
settings = tool_settings.gpencil_sculpt_paint
|
||||
elif context.mode == 'WEIGHT_GPENCIL':
|
||||
settings = ts.gpencil_weight_paint
|
||||
settings = tool_settings.gpencil_weight_paint
|
||||
elif context.mode == 'VERTEX_GPENCIL':
|
||||
settings = ts.gpencil_vertex_paint
|
||||
settings = tool_settings.gpencil_vertex_paint
|
||||
|
||||
brush = getattr(settings, "brush", None)
|
||||
# skip if no active brush
|
||||
|
@ -203,8 +203,9 @@ class VIEW3D_PT_tools_meshedit_options_automerge(View3DPanel, Panel):
|
|||
|
||||
def draw_header(self, context):
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
self.layout.prop(tool_settings, "use_mesh_automerge", text="", toggle=False)
|
||||
self.layout.use_property_split = False
|
||||
self.layout.prop(tool_settings, "use_mesh_automerge",
|
||||
text=self.bl_label if self.is_popover else "", toggle=False)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -612,7 +613,8 @@ class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel):
|
|||
|
||||
def draw_header(self, context):
|
||||
ipaint = context.tool_settings.image_paint
|
||||
self.layout.prop(ipaint, "use_stencil_layer", text="")
|
||||
self.layout.prop(ipaint, "use_stencil_layer",
|
||||
text=self.bl_label if self.is_popover else "")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -794,7 +796,8 @@ class VIEW3D_PT_tools_brush_falloff_frontface(View3DPaintPanel, Panel):
|
|||
settings = self.paint_settings(context)
|
||||
brush = settings.brush
|
||||
|
||||
self.layout.prop(brush, "use_frontface_falloff", text="")
|
||||
self.layout.prop(brush, "use_frontface_falloff",
|
||||
text=self.bl_label if self.is_popover else "")
|
||||
|
||||
def draw(self, context):
|
||||
settings = self.paint_settings(context)
|
||||
|
@ -823,7 +826,8 @@ class VIEW3D_PT_tools_brush_falloff_normal(View3DPaintPanel, Panel):
|
|||
tool_settings = context.tool_settings
|
||||
ipaint = tool_settings.image_paint
|
||||
|
||||
self.layout.prop(ipaint, "use_normal_falloff", text="")
|
||||
self.layout.prop(ipaint, "use_normal_falloff",
|
||||
text=self.bl_label if self.is_popover else "")
|
||||
|
||||
def draw(self, context):
|
||||
tool_settings = context.tool_settings
|
||||
|
@ -1273,7 +1277,8 @@ class VIEW3D_PT_tools_imagepaint_options_cavity(View3DPaintPanel, Panel):
|
|||
tool_settings = context.tool_settings
|
||||
ipaint = tool_settings.image_paint
|
||||
|
||||
self.layout.prop(ipaint, "use_cavity", text="")
|
||||
self.layout.prop(ipaint, "use_cavity",
|
||||
text=self.bl_label if self.is_popover else "")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -1615,8 +1620,9 @@ class VIEW3D_PT_tools_grease_pencil_brush_stroke(Panel, View3DPanel):
|
|||
return brush is not None and brush.gpencil_tool == 'DRAW'
|
||||
|
||||
def draw(self, _context):
|
||||
# layout = self.layout
|
||||
pass
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_grease_pencil_brush_stabilizer(Panel, View3DPanel):
|
||||
|
@ -1632,12 +1638,11 @@ class VIEW3D_PT_tools_grease_pencil_brush_stabilizer(Panel, View3DPanel):
|
|||
return brush is not None and brush.gpencil_tool == 'DRAW'
|
||||
|
||||
def draw_header(self, context):
|
||||
if self.is_popover:
|
||||
return
|
||||
|
||||
brush = context.tool_settings.gpencil_paint.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
self.layout.prop(gp_settings, "use_settings_stabilizer", text="")
|
||||
self.layout.use_property_split = False
|
||||
self.layout.prop(gp_settings, "use_settings_stabilizer",
|
||||
text=self.bl_label if self.is_popover else "")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -1647,11 +1652,6 @@ class VIEW3D_PT_tools_grease_pencil_brush_stabilizer(Panel, View3DPanel):
|
|||
brush = context.tool_settings.gpencil_paint.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
|
||||
if self.is_popover:
|
||||
row = layout.row()
|
||||
row.prop(gp_settings, "use_settings_stabilizer", text="")
|
||||
row.label(text=self.bl_label)
|
||||
|
||||
col = layout.column()
|
||||
col.active = gp_settings.use_settings_stabilizer
|
||||
|
||||
|
@ -1672,12 +1672,11 @@ class VIEW3D_PT_tools_grease_pencil_brush_post_processing(View3DPanel, Panel):
|
|||
return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL', 'TINT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
if self.is_popover:
|
||||
return
|
||||
|
||||
brush = context.tool_settings.gpencil_paint.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
self.layout.prop(gp_settings, "use_settings_postprocess", text="")
|
||||
self.layout.use_property_split = False
|
||||
self.layout.prop(gp_settings, "use_settings_postprocess",
|
||||
text=self.bl_label if self.is_popover else "")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -1687,11 +1686,6 @@ class VIEW3D_PT_tools_grease_pencil_brush_post_processing(View3DPanel, Panel):
|
|||
brush = context.tool_settings.gpencil_paint.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
|
||||
if self.is_popover:
|
||||
row = layout.row()
|
||||
row.prop(gp_settings, "use_settings_postprocess", text="")
|
||||
row.label(text=self.bl_label)
|
||||
|
||||
col = layout.column()
|
||||
col.active = gp_settings.use_settings_postprocess
|
||||
|
||||
|
@ -1734,12 +1728,11 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
|
|||
return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL', 'TINT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
if self.is_popover:
|
||||
return
|
||||
|
||||
brush = context.tool_settings.gpencil_paint.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
self.layout.prop(gp_settings, "use_settings_random", text="")
|
||||
self.layout.use_property_split = False
|
||||
self.layout.prop(gp_settings, "use_settings_random",
|
||||
text=self.bl_label if self.is_popover else "")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -1751,11 +1744,6 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
|
|||
mode = tool_settings.gpencil_paint.color_mode
|
||||
gp_settings = brush.gpencil_settings
|
||||
|
||||
if self.is_popover:
|
||||
row = layout.row()
|
||||
row.prop(gp_settings, "use_settings_random", text="")
|
||||
row.label(text=self.bl_label)
|
||||
|
||||
col = layout.column()
|
||||
col.enabled = gp_settings.use_settings_random
|
||||
|
||||
|
@ -1828,8 +1816,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_paint
|
||||
brush = settings.brush
|
||||
if brush is None:
|
||||
return False
|
||||
|
@ -1946,8 +1934,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_sculpt_falloff(GreasePencilBrushFallof
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_sculpt_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_sculpt_paint
|
||||
return (settings and settings.brush and settings.brush.curve)
|
||||
|
||||
|
||||
|
@ -2055,8 +2043,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_weight_falloff(GreasePencilBrushFallof
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_weight_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_weight_paint
|
||||
brush = settings.brush
|
||||
return (brush and brush.curve)
|
||||
|
||||
|
@ -2131,8 +2119,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_vertex_color(View3DPanel, Panel):
|
|||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_vertex_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_vertex_paint
|
||||
brush = settings.brush
|
||||
|
||||
if ob is None or brush is None:
|
||||
|
@ -2147,8 +2135,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_vertex_color(View3DPanel, Panel):
|
|||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_vertex_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_vertex_paint
|
||||
brush = settings.brush
|
||||
|
||||
col = layout.column()
|
||||
|
@ -2169,8 +2157,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_vertex_falloff(GreasePencilBrushFallof
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_vertex_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_vertex_paint
|
||||
return (settings and settings.brush and settings.brush.curve)
|
||||
|
||||
|
||||
|
@ -2183,8 +2171,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_vertex_palette(View3DPanel, Panel):
|
|||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_vertex_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_vertex_paint
|
||||
brush = settings.brush
|
||||
|
||||
if ob is None or brush is None:
|
||||
|
@ -2199,8 +2187,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_vertex_palette(View3DPanel, Panel):
|
|||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_vertex_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_vertex_paint
|
||||
|
||||
col = layout.column()
|
||||
|
||||
|
@ -2218,8 +2206,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_mixcolor(View3DPanel, Panel):
|
|||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_paint
|
||||
brush = settings.brush
|
||||
|
||||
if ob is None or brush is None:
|
||||
|
@ -2243,8 +2231,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_mixcolor(View3DPanel, Panel):
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_paint
|
||||
brush = settings.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
|
||||
|
@ -2282,8 +2270,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_mix_palette(View3DPanel, Panel):
|
|||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_paint
|
||||
brush = settings.brush
|
||||
|
||||
if ob is None or brush is None:
|
||||
|
@ -2306,8 +2294,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_mix_palette(View3DPanel, Panel):
|
|||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
ts = context.tool_settings
|
||||
settings = ts.gpencil_paint
|
||||
tool_settings = context.tool_settings
|
||||
settings = tool_settings.gpencil_paint
|
||||
brush = settings.brush
|
||||
|
||||
col = layout.column()
|
||||
|
|
|
@ -29,8 +29,8 @@ set(SRC_DNA_INC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_fluid_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_freestyle_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_genfile.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_legacy_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpu_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_image_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_ipo_types.h
|
||||
|
|
|
@ -802,7 +802,6 @@ class CustomDataAttributes {
|
|||
|
||||
std::optional<blender::GMutableSpan> get_for_write(const AttributeIDRef &attribute_id);
|
||||
bool create(const AttributeIDRef &attribute_id, eCustomDataType data_type);
|
||||
bool create_by_move(const AttributeIDRef &attribute_id, eCustomDataType data_type, void *buffer);
|
||||
bool remove(const AttributeIDRef &attribute_id);
|
||||
|
||||
bool foreach_attribute(const AttributeForeachCallback callback, eAttrDomain domain) const;
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "DNA_color_types.h"
|
||||
#include "DNA_object_enums.h"
|
||||
|
||||
#include "BKE_paint.h" /* for ePaintMode */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -185,6 +187,11 @@ void BKE_brush_scale_size(int *r_brush_size,
|
|||
float new_unprojected_radius,
|
||||
float old_unprojected_radius);
|
||||
|
||||
/* Returns true if a brush requires a cube
|
||||
* (often presented to the user as a square) tip inside a specific paint mode.
|
||||
*/
|
||||
bool BKE_brush_has_cube_tip(const struct Brush *brush, ePaintMode paint_mode);
|
||||
|
||||
/* Accessors */
|
||||
#define BKE_brush_tool_get(brush, p) \
|
||||
(CHECK_TYPE_ANY(brush, struct Brush *, const struct Brush *), \
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_implicit_sharing.h"
|
||||
#include "BLI_sys_types.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#ifdef __cplusplus
|
||||
|
@ -74,14 +75,8 @@ extern const CustomData_MeshMasks CD_MASK_EVERYTHING;
|
|||
|
||||
/** Add/copy/merge allocation types. */
|
||||
typedef enum eCDAllocType {
|
||||
/** Use the data pointer. */
|
||||
CD_ASSIGN = 0,
|
||||
/** Allocate and set to default, which is usually just zeroed memory. */
|
||||
CD_SET_DEFAULT = 2,
|
||||
/** Use data pointers, set layer flag NOFREE. */
|
||||
CD_REFERENCE = 3,
|
||||
/** Do a full copy of all layers, only allowed if source has same number of elements. */
|
||||
CD_DUPLICATE = 4,
|
||||
/**
|
||||
* Default construct new layer values. Does nothing for trivial types. This should be used
|
||||
* if all layer values will be set by the caller after creating the layer.
|
||||
|
@ -158,28 +153,43 @@ void CustomData_data_multiply(eCustomDataType type, void *data, float fac);
|
|||
void CustomData_data_add(eCustomDataType type, void *data1, const void *data2);
|
||||
|
||||
/**
|
||||
* Initializes a CustomData object with the same layer setup as source.
|
||||
* mask is a bit-field where `(mask & (1 << (layer type)))` indicates
|
||||
* if a layer should be copied or not. alloctype must be one of the above.
|
||||
* Initializes a CustomData object with the same layer setup as source. `mask` is a bit-field where
|
||||
* `(mask & (1 << (layer type)))` indicates if a layer should be copied or not. Data layers using
|
||||
* implicit-sharing will not actually be copied but will be shared between source and destination.
|
||||
*/
|
||||
void CustomData_copy(const struct CustomData *source,
|
||||
struct CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
eCDAllocType alloctype,
|
||||
int totelem);
|
||||
/**
|
||||
* Initializes a CustomData object with the same layers as source. The data is not copied from the
|
||||
* source. Instead, the new layers are initialized using the given `alloctype`.
|
||||
*/
|
||||
void CustomData_copy_layout(const struct CustomData *source,
|
||||
struct CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
eCDAllocType alloctype,
|
||||
int totelem);
|
||||
|
||||
/* BMESH_TODO, not really a public function but readfile.c needs it */
|
||||
void CustomData_update_typemap(struct CustomData *data);
|
||||
|
||||
/**
|
||||
* Same as the above, except that this will preserve existing layers, and only
|
||||
* add the layers that were not there yet.
|
||||
* Copies all layers from source to destination that don't exist there yet.
|
||||
*/
|
||||
bool CustomData_merge(const struct CustomData *source,
|
||||
struct CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
eCDAllocType alloctype,
|
||||
int totelem);
|
||||
/**
|
||||
* Copies all layers from source to destination that don't exist there yet. The layer data is not
|
||||
* copied. Instead the newly created layers are initialized using the given `alloctype`.
|
||||
*/
|
||||
bool CustomData_merge_layout(const struct CustomData *source,
|
||||
struct CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
eCDAllocType alloctype,
|
||||
int totelem);
|
||||
|
||||
/**
|
||||
* Reallocate custom data to a new element count. If the new size is larger, the new values use
|
||||
|
@ -189,16 +199,16 @@ bool CustomData_merge(const struct CustomData *source,
|
|||
void CustomData_realloc(struct CustomData *data, int old_size, int new_size);
|
||||
|
||||
/**
|
||||
* BMesh version of CustomData_merge; merges the layouts of source and `dest`,
|
||||
* BMesh version of CustomData_merge_layout; merges the layouts of source and `dest`,
|
||||
* then goes through the mesh and makes sure all the custom-data blocks are
|
||||
* consistent with the new layout.
|
||||
*/
|
||||
bool CustomData_bmesh_merge(const struct CustomData *source,
|
||||
struct CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
eCDAllocType alloctype,
|
||||
struct BMesh *bm,
|
||||
char htype);
|
||||
bool CustomData_bmesh_merge_layout(const struct CustomData *source,
|
||||
struct CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
eCDAllocType alloctype,
|
||||
struct BMesh *bm,
|
||||
char htype);
|
||||
|
||||
/**
|
||||
* Remove layers that aren't stored in BMesh or are stored as flags on BMesh.
|
||||
|
@ -229,18 +239,25 @@ void CustomData_free_typemask(struct CustomData *data, int totelem, eCustomDataM
|
|||
void CustomData_free_temporary(struct CustomData *data, int totelem);
|
||||
|
||||
/**
|
||||
* Adds a data layer of the given type to the #CustomData object, optionally
|
||||
* backed by an external data array. the different allocation types are
|
||||
* defined above. returns the data of the layer.
|
||||
* Adds a layer of the given type to the #CustomData object. The new layer is initialized based on
|
||||
* the given alloctype.
|
||||
* \return The layer data.
|
||||
*/
|
||||
void *CustomData_add_layer(struct CustomData *data,
|
||||
eCustomDataType type,
|
||||
eCDAllocType alloctype,
|
||||
int totelem);
|
||||
|
||||
/**
|
||||
* Adds a layer of the given type to the #CustomData object. The new layer takes ownership of the
|
||||
* passed in `layer_data`. If a #ImplicitSharingInfoHandle is passed in, its user count is
|
||||
* increased.
|
||||
*/
|
||||
const void *CustomData_add_layer_with_data(struct CustomData *data,
|
||||
eCustomDataType type,
|
||||
void *layer_data,
|
||||
int totelem);
|
||||
int totelem,
|
||||
const ImplicitSharingInfoHandle *sharing_info);
|
||||
|
||||
/**
|
||||
* Same as above but accepts a name.
|
||||
|
@ -250,17 +267,26 @@ void *CustomData_add_layer_named(struct CustomData *data,
|
|||
eCDAllocType alloctype,
|
||||
int totelem,
|
||||
const char *name);
|
||||
|
||||
const void *CustomData_add_layer_named_with_data(struct CustomData *data,
|
||||
eCustomDataType type,
|
||||
void *layer_data,
|
||||
int totelem,
|
||||
const char *name);
|
||||
const char *name,
|
||||
const ImplicitSharingInfoHandle *sharing_info);
|
||||
|
||||
void *CustomData_add_layer_anonymous(struct CustomData *data,
|
||||
eCustomDataType type,
|
||||
eCDAllocType alloctype,
|
||||
void *layer,
|
||||
int totelem,
|
||||
const AnonymousAttributeIDHandle *anonymous_id);
|
||||
const void *CustomData_add_layer_anonymous_with_data(
|
||||
struct CustomData *data,
|
||||
eCustomDataType type,
|
||||
const AnonymousAttributeIDHandle *anonymous_id,
|
||||
int totelem,
|
||||
void *layer_data,
|
||||
const ImplicitSharingInfoHandle *sharing_info);
|
||||
|
||||
/**
|
||||
* Frees the active or first data layer with the give type.
|
||||
|
@ -296,11 +322,6 @@ int CustomData_number_of_layers(const struct CustomData *data, eCustomDataType t
|
|||
int CustomData_number_of_anonymous_layers(const struct CustomData *data, eCustomDataType type);
|
||||
int CustomData_number_of_layers_typemask(const struct CustomData *data, eCustomDataMask mask);
|
||||
|
||||
/**
|
||||
* Duplicate all the layers with flag NOFREE, and remove the flag from duplicated layers.
|
||||
*/
|
||||
void CustomData_duplicate_referenced_layers(CustomData *data, int totelem);
|
||||
|
||||
/**
|
||||
* Set the #CD_FLAG_NOCOPY flag in custom data layers where the mask is
|
||||
* zero for the layer type, so only layer types specified by the mask will be copied
|
||||
|
|
|
@ -122,7 +122,18 @@ void BKE_mesh_looptri_get_real_edges(const struct MEdge *edges,
|
|||
* Only use for undo, in most cases `BKE_id_free(nullptr, me)` should be used.
|
||||
*/
|
||||
void BKE_mesh_free_data_for_undo(struct Mesh *me);
|
||||
|
||||
/**
|
||||
* Remove all geometry and derived data like caches from the mesh.
|
||||
*/
|
||||
void BKE_mesh_clear_geometry(struct Mesh *me);
|
||||
|
||||
/**
|
||||
* Same as #BKE_mesh_clear_geometry, but also clears attribute meta-data like active attribute
|
||||
* names and vertex group names. Used when the geometry is *entirely* replaced.
|
||||
*/
|
||||
void BKE_mesh_clear_geometry_and_metadata(struct Mesh *me);
|
||||
|
||||
struct Mesh *BKE_mesh_add(struct Main *bmain, const char *name);
|
||||
|
||||
void BKE_mesh_free_editmesh(struct Mesh *mesh);
|
||||
|
|
|
@ -48,6 +48,7 @@ struct PaintCurve;
|
|||
struct PaintModeSettings;
|
||||
struct Palette;
|
||||
struct PaletteColor;
|
||||
struct RegionView3D;
|
||||
struct Scene;
|
||||
struct StrokeCache;
|
||||
struct Sculpt;
|
||||
|
@ -238,7 +239,8 @@ void BKE_paint_face_set_overlay_color_get(int face_set, int seed, uchar r_color[
|
|||
|
||||
bool paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups,
|
||||
struct Brush *brush,
|
||||
const float mouse_pos[2]);
|
||||
const float mouse_pos[2],
|
||||
ePaintMode paint_mode);
|
||||
void paint_update_brush_rake_rotation(struct UnifiedPaintSettings *ups,
|
||||
struct Brush *brush,
|
||||
float rotation);
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
# include "BLI_bounds_types.hh"
|
||||
# include "BLI_math_vector_types.hh"
|
||||
# include "BLI_shared_cache.hh"
|
||||
|
||||
# include "DNA_pointcloud_types.h"
|
||||
|
||||
# include "BKE_customdata.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -45,6 +49,21 @@ struct PointCloudRuntime {
|
|||
};
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
inline blender::Span<blender::float3> PointCloud::positions() const
|
||||
{
|
||||
return {static_cast<const blender::float3 *>(
|
||||
CustomData_get_layer_named(&this->pdata, CD_PROP_FLOAT3, "position")),
|
||||
this->totpoint};
|
||||
}
|
||||
|
||||
inline blender::MutableSpan<blender::float3> PointCloud::positions_for_write()
|
||||
{
|
||||
return {static_cast<blender::float3 *>(CustomData_get_layer_named_for_write(
|
||||
&this->pdata, CD_PROP_FLOAT3, "position", this->totpoint)),
|
||||
this->totpoint};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void *BKE_pointcloud_add(struct Main *bmain, const char *name);
|
||||
|
|
|
@ -144,9 +144,9 @@ set(SRC
|
|||
intern/geometry_fields.cc
|
||||
intern/geometry_set.cc
|
||||
intern/geometry_set_instances.cc
|
||||
intern/gpencil_legacy.c
|
||||
intern/gpencil_curve_legacy.c
|
||||
intern/gpencil_geom_legacy.cc
|
||||
intern/gpencil_legacy.c
|
||||
intern/gpencil_modifier_legacy.c
|
||||
intern/gpencil_update_cache_legacy.c
|
||||
intern/icons.cc
|
||||
|
@ -384,9 +384,9 @@ set(SRC
|
|||
BKE_geometry_set.hh
|
||||
BKE_geometry_set_instances.hh
|
||||
BKE_global.h
|
||||
BKE_gpencil_legacy.h
|
||||
BKE_gpencil_curve_legacy.h
|
||||
BKE_gpencil_geom_legacy.h
|
||||
BKE_gpencil_legacy.h
|
||||
BKE_gpencil_modifier_legacy.h
|
||||
BKE_gpencil_update_cache_legacy.h
|
||||
BKE_icons.h
|
||||
|
|
|
@ -207,11 +207,12 @@ void DM_from_template(DerivedMesh *dm,
|
|||
int numPolys)
|
||||
{
|
||||
const CustomData_MeshMasks *mask = &CD_MASK_DERIVEDMESH;
|
||||
CustomData_copy(&source->vertData, &dm->vertData, mask->vmask, CD_SET_DEFAULT, numVerts);
|
||||
CustomData_copy(&source->edgeData, &dm->edgeData, mask->emask, CD_SET_DEFAULT, numEdges);
|
||||
CustomData_copy(&source->faceData, &dm->faceData, mask->fmask, CD_SET_DEFAULT, numTessFaces);
|
||||
CustomData_copy(&source->loopData, &dm->loopData, mask->lmask, CD_SET_DEFAULT, numLoops);
|
||||
CustomData_copy(&source->polyData, &dm->polyData, mask->pmask, CD_SET_DEFAULT, numPolys);
|
||||
CustomData_copy_layout(&source->vertData, &dm->vertData, mask->vmask, CD_SET_DEFAULT, numVerts);
|
||||
CustomData_copy_layout(&source->edgeData, &dm->edgeData, mask->emask, CD_SET_DEFAULT, numEdges);
|
||||
CustomData_copy_layout(
|
||||
&source->faceData, &dm->faceData, mask->fmask, CD_SET_DEFAULT, numTessFaces);
|
||||
CustomData_copy_layout(&source->loopData, &dm->loopData, mask->lmask, CD_SET_DEFAULT, numLoops);
|
||||
CustomData_copy_layout(&source->polyData, &dm->polyData, mask->pmask, CD_SET_DEFAULT, numPolys);
|
||||
dm->poly_offsets = static_cast<int *>(MEM_dupallocN(source->poly_offsets));
|
||||
|
||||
dm->type = type;
|
||||
|
@ -699,7 +700,12 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
|
|||
* places that wish to use the original mesh but with deformed
|
||||
* coordinates (like vertex paint). */
|
||||
if (r_deform) {
|
||||
mesh_deform = BKE_mesh_copy_for_eval(mesh_final, false);
|
||||
if (mesh_final) {
|
||||
mesh_deform = BKE_mesh_copy_for_eval(mesh_final, false);
|
||||
}
|
||||
else {
|
||||
mesh_deform = BKE_mesh_copy_for_eval(mesh_input, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -201,13 +201,16 @@ static bool add_builtin_type_custom_data_layer_from_init(CustomData &custom_data
|
|||
return true;
|
||||
}
|
||||
case AttributeInit::Type::MoveArray: {
|
||||
void *source_data = static_cast<const AttributeInitMoveArray &>(initializer).data;
|
||||
const void *data = CustomData_add_layer_with_data(
|
||||
&custom_data, data_type, source_data, domain_num);
|
||||
if (data == nullptr) {
|
||||
MEM_freeN(source_data);
|
||||
void *src_data = static_cast<const AttributeInitMoveArray &>(initializer).data;
|
||||
const void *stored_data = CustomData_add_layer_with_data(
|
||||
&custom_data, data_type, src_data, domain_num, nullptr);
|
||||
if (stored_data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (stored_data != src_data) {
|
||||
MEM_freeN(src_data);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -230,25 +233,26 @@ static void *add_generic_custom_data_layer(CustomData &custom_data,
|
|||
}
|
||||
const AnonymousAttributeID &anonymous_id = attribute_id.anonymous_id();
|
||||
return CustomData_add_layer_anonymous(
|
||||
&custom_data, data_type, alloctype, nullptr, domain_size, &anonymous_id);
|
||||
&custom_data, data_type, alloctype, domain_size, &anonymous_id);
|
||||
}
|
||||
|
||||
static const void *add_generic_custom_data_layer_with_existing_data(
|
||||
CustomData &custom_data,
|
||||
const eCustomDataType data_type,
|
||||
void *layer_data,
|
||||
const AttributeIDRef &attribute_id,
|
||||
const int domain_size,
|
||||
const AttributeIDRef &attribute_id)
|
||||
void *layer_data,
|
||||
const ImplicitSharingInfo *sharing_info)
|
||||
{
|
||||
if (!attribute_id.is_anonymous()) {
|
||||
char attribute_name_c[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
attribute_id.name().copy(attribute_name_c);
|
||||
return CustomData_add_layer_named_with_data(
|
||||
&custom_data, data_type, layer_data, domain_size, attribute_name_c);
|
||||
if (attribute_id.is_anonymous()) {
|
||||
const AnonymousAttributeID &anonymous_id = attribute_id.anonymous_id();
|
||||
return CustomData_add_layer_anonymous_with_data(
|
||||
&custom_data, data_type, &anonymous_id, domain_size, layer_data, sharing_info);
|
||||
}
|
||||
const AnonymousAttributeID &anonymous_id = attribute_id.anonymous_id();
|
||||
return CustomData_add_layer_anonymous(
|
||||
&custom_data, data_type, CD_ASSIGN, layer_data, domain_size, &anonymous_id);
|
||||
char attribute_name_c[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
attribute_id.name().copy(attribute_name_c);
|
||||
return CustomData_add_layer_named_with_data(
|
||||
&custom_data, data_type, layer_data, domain_size, attribute_name_c, sharing_info);
|
||||
}
|
||||
|
||||
static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attribute_id,
|
||||
|
@ -279,9 +283,9 @@ static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attr
|
|||
break;
|
||||
}
|
||||
case AttributeInit::Type::MoveArray: {
|
||||
void *source_data = static_cast<const AttributeInitMoveArray &>(initializer).data;
|
||||
void *data = static_cast<const AttributeInitMoveArray &>(initializer).data;
|
||||
add_generic_custom_data_layer_with_existing_data(
|
||||
custom_data, data_type, source_data, domain_num, attribute_id);
|
||||
custom_data, data_type, attribute_id, domain_num, data, nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -571,7 +575,7 @@ CustomDataAttributes::~CustomDataAttributes()
|
|||
CustomDataAttributes::CustomDataAttributes(const CustomDataAttributes &other)
|
||||
{
|
||||
size_ = other.size_;
|
||||
CustomData_copy(&other.data, &data, CD_MASK_ALL, CD_DUPLICATE, size_);
|
||||
CustomData_copy(&other.data, &data, CD_MASK_ALL, size_);
|
||||
}
|
||||
|
||||
CustomDataAttributes::CustomDataAttributes(CustomDataAttributes &&other)
|
||||
|
@ -655,15 +659,6 @@ bool CustomDataAttributes::create(const AttributeIDRef &attribute_id,
|
|||
return result != nullptr;
|
||||
}
|
||||
|
||||
bool CustomDataAttributes::create_by_move(const AttributeIDRef &attribute_id,
|
||||
const eCustomDataType data_type,
|
||||
void *buffer)
|
||||
{
|
||||
const void *result = add_generic_custom_data_layer_with_existing_data(
|
||||
data, data_type, buffer, size_, attribute_id);
|
||||
return result != nullptr;
|
||||
}
|
||||
|
||||
bool CustomDataAttributes::remove(const AttributeIDRef &attribute_id)
|
||||
{
|
||||
for (const int i : IndexRange(data.totlayer)) {
|
||||
|
|
|
@ -2576,3 +2576,26 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool
|
|||
|
||||
return im;
|
||||
}
|
||||
|
||||
bool BKE_brush_has_cube_tip(const Brush *brush, ePaintMode paint_mode)
|
||||
{
|
||||
switch (paint_mode) {
|
||||
case PAINT_MODE_SCULPT: {
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_MULTIPLANE_SCRAPE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ELEM(brush->sculpt_tool, SCULPT_TOOL_CLAY_STRIPS, SCULPT_TOOL_PAINT) &&
|
||||
brush->tip_roundness < 1.0f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "BKE_editmesh.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_runtime.h"
|
||||
#include "BKE_pointcloud.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
@ -1425,10 +1426,7 @@ BVHTree *BKE_bvhtree_from_pointcloud_get(BVHTreeFromPointCloud *data,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
blender::bke::AttributeAccessor attributes = pointcloud->attributes();
|
||||
blender::VArraySpan<blender::float3> positions = attributes.lookup_or_default<blender::float3>(
|
||||
"position", ATTR_DOMAIN_POINT, blender::float3(0));
|
||||
|
||||
const Span<float3> positions = pointcloud->positions();
|
||||
for (const int i : positions.index_range()) {
|
||||
BLI_bvhtree_insert(tree, i, positions[i], 1);
|
||||
}
|
||||
|
|
|
@ -147,9 +147,7 @@ static CDDerivedMesh *cdDM_create(const char *desc)
|
|||
return cddm;
|
||||
}
|
||||
|
||||
static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
|
||||
eCDAllocType alloctype,
|
||||
const CustomData_MeshMasks *mask)
|
||||
static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh, const CustomData_MeshMasks *mask)
|
||||
{
|
||||
CDDerivedMesh *cddm = cdDM_create(__func__);
|
||||
DerivedMesh *dm = &cddm->dm;
|
||||
|
@ -167,15 +165,14 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
|
|||
mesh->totloop,
|
||||
mesh->totpoly);
|
||||
|
||||
CustomData_merge(&mesh->vdata, &dm->vertData, cddata_masks.vmask, alloctype, mesh->totvert);
|
||||
CustomData_merge(&mesh->edata, &dm->edgeData, cddata_masks.emask, alloctype, mesh->totedge);
|
||||
CustomData_merge(&mesh->vdata, &dm->vertData, cddata_masks.vmask, mesh->totvert);
|
||||
CustomData_merge(&mesh->edata, &dm->edgeData, cddata_masks.emask, mesh->totedge);
|
||||
CustomData_merge(&mesh->fdata,
|
||||
&dm->faceData,
|
||||
cddata_masks.fmask | CD_MASK_ORIGINDEX,
|
||||
alloctype,
|
||||
0 /* `mesh->totface` */);
|
||||
CustomData_merge(&mesh->ldata, &dm->loopData, cddata_masks.lmask, alloctype, mesh->totloop);
|
||||
CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, alloctype, mesh->totpoly);
|
||||
CustomData_merge(&mesh->ldata, &dm->loopData, cddata_masks.lmask, mesh->totloop);
|
||||
CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, mesh->totpoly);
|
||||
|
||||
cddm->vert_positions = static_cast<float(*)[3]>(CustomData_get_layer_named_for_write(
|
||||
&dm->vertData, CD_PROP_FLOAT3, "position", mesh->totvert));
|
||||
|
@ -203,5 +200,5 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
|
|||
|
||||
DerivedMesh *CDDM_from_mesh(Mesh *mesh)
|
||||
{
|
||||
return cdDM_from_mesh_ex(mesh, CD_REFERENCE, &CD_MASK_MESH);
|
||||
return cdDM_from_mesh_ex(mesh, &CD_MASK_MESH);
|
||||
}
|
||||
|
|
|
@ -80,6 +80,9 @@ static KnotsMode knots_mode_from_legacy(const short flag)
|
|||
Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_list)
|
||||
{
|
||||
const Vector<const Nurb *> src_curves(nurbs_list);
|
||||
if (src_curves.is_empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Curves *curves_id = curves_new_nomain(0, src_curves.size());
|
||||
CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
|
@ -104,10 +107,6 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_
|
|||
|
||||
curves.update_curve_types();
|
||||
|
||||
if (curves.curves_num() == 0) {
|
||||
return curves_id;
|
||||
}
|
||||
|
||||
const OffsetIndices points_by_curve = curves.points_by_curve();
|
||||
MutableSpan<float3> positions = curves.positions_for_write();
|
||||
SpanAttributeWriter<float> radius_attribute =
|
||||
|
|
|
@ -62,45 +62,18 @@ static void curves_init_data(ID *id)
|
|||
new (&curves->geometry) blender::bke::CurvesGeometry();
|
||||
}
|
||||
|
||||
static void curves_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag)
|
||||
static void curves_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/)
|
||||
{
|
||||
using namespace blender;
|
||||
|
||||
Curves *curves_dst = (Curves *)id_dst;
|
||||
const Curves *curves_src = (const Curves *)id_src;
|
||||
curves_dst->mat = static_cast<Material **>(MEM_dupallocN(curves_src->mat));
|
||||
|
||||
const bke::CurvesGeometry &src = curves_src->geometry.wrap();
|
||||
bke::CurvesGeometry &dst = curves_dst->geometry.wrap();
|
||||
|
||||
/* We need special handling here because the generic ID management code has already done a
|
||||
* shallow copy from the source to the destination, and because the copy-on-write functionality
|
||||
* isn't supported more generically yet. */
|
||||
|
||||
dst.point_num = src.point_num;
|
||||
dst.curve_num = src.curve_num;
|
||||
|
||||
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
|
||||
CustomData_copy(&src.point_data, &dst.point_data, CD_MASK_ALL, alloc_type, dst.point_num);
|
||||
CustomData_copy(&src.curve_data, &dst.curve_data, CD_MASK_ALL, alloc_type, dst.curve_num);
|
||||
|
||||
dst.curve_offsets = static_cast<int *>(MEM_dupallocN(src.curve_offsets));
|
||||
new (&curves_dst->geometry) blender::bke::CurvesGeometry(curves_src->geometry.wrap());
|
||||
|
||||
if (curves_src->surface_uv_map != nullptr) {
|
||||
curves_dst->surface_uv_map = BLI_strdup(curves_src->surface_uv_map);
|
||||
}
|
||||
|
||||
dst.runtime = MEM_new<bke::CurvesGeometryRuntime>(__func__);
|
||||
|
||||
dst.runtime->type_counts = src.runtime->type_counts;
|
||||
dst.runtime->evaluated_offsets_cache = src.runtime->evaluated_offsets_cache;
|
||||
dst.runtime->nurbs_basis_cache = src.runtime->nurbs_basis_cache;
|
||||
dst.runtime->evaluated_position_cache = src.runtime->evaluated_position_cache;
|
||||
dst.runtime->bounds_cache = src.runtime->bounds_cache;
|
||||
dst.runtime->evaluated_length_cache = src.runtime->evaluated_length_cache;
|
||||
dst.runtime->evaluated_tangent_cache = src.runtime->evaluated_tangent_cache;
|
||||
dst.runtime->evaluated_normal_cache = src.runtime->evaluated_normal_cache;
|
||||
|
||||
curves_dst->batch_cache = nullptr;
|
||||
}
|
||||
|
||||
|
@ -156,11 +129,6 @@ static void curves_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
|
||||
BLO_read_data_address(reader, &curves->surface_uv_map);
|
||||
|
||||
curves->geometry.runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__);
|
||||
|
||||
/* Recalculate curve type count cache that isn't saved in files. */
|
||||
curves->geometry.wrap().update_curve_types();
|
||||
|
||||
/* Materials */
|
||||
BLO_read_pointer_array(reader, (void **)&curves->mat);
|
||||
}
|
||||
|
|
|
@ -80,8 +80,8 @@ static void copy_curves_geometry(CurvesGeometry &dst, const CurvesGeometry &src)
|
|||
CustomData_free(&dst.curve_data, dst.curve_num);
|
||||
dst.point_num = src.point_num;
|
||||
dst.curve_num = src.curve_num;
|
||||
CustomData_copy(&src.point_data, &dst.point_data, CD_MASK_ALL, CD_DUPLICATE, dst.point_num);
|
||||
CustomData_copy(&src.curve_data, &dst.curve_data, CD_MASK_ALL, CD_DUPLICATE, dst.curve_num);
|
||||
CustomData_copy(&src.point_data, &dst.point_data, CD_MASK_ALL, dst.point_num);
|
||||
CustomData_copy(&src.curve_data, &dst.curve_data, CD_MASK_ALL, dst.curve_num);
|
||||
|
||||
MEM_SAFE_FREE(dst.curve_offsets);
|
||||
dst.curve_offsets = (int *)MEM_malloc_arrayN(dst.point_num + 1, sizeof(int), __func__);
|
||||
|
@ -100,8 +100,7 @@ static void copy_curves_geometry(CurvesGeometry &dst, const CurvesGeometry &src)
|
|||
dst.runtime->evaluated_normal_cache = src.runtime->evaluated_normal_cache;
|
||||
}
|
||||
|
||||
CurvesGeometry::CurvesGeometry(const CurvesGeometry &other)
|
||||
: CurvesGeometry(other.point_num, other.curve_num)
|
||||
CurvesGeometry::CurvesGeometry(const CurvesGeometry &other) : CurvesGeometry()
|
||||
{
|
||||
copy_curves_geometry(*this, other);
|
||||
}
|
||||
|
@ -133,8 +132,7 @@ static void move_curves_geometry(CurvesGeometry &dst, CurvesGeometry &src)
|
|||
std::swap(dst.runtime, src.runtime);
|
||||
}
|
||||
|
||||
CurvesGeometry::CurvesGeometry(CurvesGeometry &&other)
|
||||
: CurvesGeometry(other.point_num, other.curve_num)
|
||||
CurvesGeometry::CurvesGeometry(CurvesGeometry &&other) : CurvesGeometry()
|
||||
{
|
||||
move_curves_geometry(*this, other);
|
||||
}
|
||||
|
@ -1582,10 +1580,15 @@ GVArray CurvesGeometry::adapt_domain(const GVArray &varray,
|
|||
|
||||
void CurvesGeometry::blend_read(BlendDataReader &reader)
|
||||
{
|
||||
this->runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__);
|
||||
|
||||
CustomData_blend_read(&reader, &this->point_data, this->point_num);
|
||||
CustomData_blend_read(&reader, &this->curve_data, this->curve_num);
|
||||
|
||||
BLO_read_int32_array(&reader, this->curve_num + 1, &this->curve_offsets);
|
||||
|
||||
/* Recalculate curve type count cache that isn't saved in files. */
|
||||
this->update_curve_types();
|
||||
}
|
||||
|
||||
void CurvesGeometry::blend_write(BlendWriter &writer, ID &id)
|
||||
|
|
|
@ -101,11 +101,8 @@ void fill_points(const OffsetIndices<int> points_by_curve,
|
|||
bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves)
|
||||
{
|
||||
bke::CurvesGeometry dst_curves(0, src_curves.curves_num());
|
||||
CustomData_copy(&src_curves.curve_data,
|
||||
&dst_curves.curve_data,
|
||||
CD_MASK_ALL,
|
||||
CD_DUPLICATE,
|
||||
src_curves.curves_num());
|
||||
CustomData_copy(
|
||||
&src_curves.curve_data, &dst_curves.curve_data, CD_MASK_ALL, src_curves.curves_num());
|
||||
dst_curves.runtime->type_counts = src_curves.runtime->type_counts;
|
||||
return dst_curves;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include "data_transfer_intern.h"
|
||||
|
||||
using blender::float2;
|
||||
using blender::ImplicitSharingInfo;
|
||||
using blender::IndexRange;
|
||||
using blender::Set;
|
||||
using blender::Span;
|
||||
|
@ -2158,12 +2159,14 @@ void customData_mask_layers__print(const CustomData_MeshMasks *mask)
|
|||
|
||||
static void customData_update_offsets(CustomData *data);
|
||||
|
||||
static CustomDataLayer *customData_add_layer__internal(CustomData *data,
|
||||
eCustomDataType type,
|
||||
eCDAllocType alloctype,
|
||||
void *layerdata,
|
||||
int totelem,
|
||||
const char *name);
|
||||
static CustomDataLayer *customData_add_layer__internal(
|
||||
CustomData *data,
|
||||
eCustomDataType type,
|
||||
std::optional<eCDAllocType> alloctype,
|
||||
void *layer_data_to_assign,
|
||||
const ImplicitSharingInfo *sharing_info_to_assign,
|
||||
int totelem,
|
||||
const char *name);
|
||||
|
||||
void CustomData_update_typemap(CustomData *data)
|
||||
{
|
||||
|
@ -2192,93 +2195,113 @@ static bool customdata_typemap_is_valid(const CustomData *data)
|
|||
}
|
||||
#endif
|
||||
|
||||
bool CustomData_merge(const CustomData *source,
|
||||
CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
eCDAllocType alloctype,
|
||||
int totelem)
|
||||
static void *copy_layer_data(const eCustomDataType type, const void *data, const int totelem)
|
||||
{
|
||||
const LayerTypeInfo &type_info = *layerType_getInfo(type);
|
||||
if (type_info.copy) {
|
||||
void *new_data = MEM_malloc_arrayN(size_t(totelem), type_info.size, __func__);
|
||||
type_info.copy(data, new_data, totelem);
|
||||
return new_data;
|
||||
}
|
||||
return MEM_dupallocN(data);
|
||||
}
|
||||
|
||||
static void free_layer_data(const eCustomDataType type, const void *data, const int totelem)
|
||||
{
|
||||
const LayerTypeInfo &type_info = *layerType_getInfo(type);
|
||||
if (type_info.free) {
|
||||
type_info.free(const_cast<void *>(data), totelem, type_info.size);
|
||||
}
|
||||
MEM_freeN(const_cast<void *>(data));
|
||||
}
|
||||
|
||||
static bool customdata_merge_internal(const CustomData *source,
|
||||
CustomData *dest,
|
||||
const eCustomDataMask mask,
|
||||
const std::optional<eCDAllocType> alloctype,
|
||||
const int totelem)
|
||||
{
|
||||
// const LayerTypeInfo *typeInfo;
|
||||
CustomDataLayer *layer, *newlayer;
|
||||
int lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0;
|
||||
int number = 0, maxnumber = -1;
|
||||
bool changed = false;
|
||||
|
||||
int last_type = -1;
|
||||
int last_active = 0;
|
||||
int last_render = 0;
|
||||
int last_clone = 0;
|
||||
int last_mask = 0;
|
||||
int current_type_layer_count = 0;
|
||||
int max_current_type_layer_count = -1;
|
||||
|
||||
for (int i = 0; i < source->totlayer; i++) {
|
||||
layer = &source->layers[i];
|
||||
// typeInfo = layerType_getInfo(eCustomDataType(layer->type)); /* UNUSED */
|
||||
const CustomDataLayer &src_layer = source->layers[i];
|
||||
const eCustomDataType type = eCustomDataType(src_layer.type);
|
||||
const int src_layer_flag = src_layer.flag;
|
||||
|
||||
const eCustomDataType type = eCustomDataType(layer->type);
|
||||
int flag = layer->flag;
|
||||
|
||||
if (type != lasttype) {
|
||||
number = 0;
|
||||
maxnumber = CustomData_layertype_layers_max(type);
|
||||
lastactive = layer->active;
|
||||
lastrender = layer->active_rnd;
|
||||
lastclone = layer->active_clone;
|
||||
lastmask = layer->active_mask;
|
||||
lasttype = type;
|
||||
if (type != last_type) {
|
||||
current_type_layer_count = 0;
|
||||
max_current_type_layer_count = CustomData_layertype_layers_max(type);
|
||||
last_active = src_layer.active;
|
||||
last_render = src_layer.active_rnd;
|
||||
last_clone = src_layer.active_clone;
|
||||
last_mask = src_layer.active_mask;
|
||||
last_type = type;
|
||||
}
|
||||
else {
|
||||
number++;
|
||||
current_type_layer_count++;
|
||||
}
|
||||
|
||||
if (flag & CD_FLAG_NOCOPY) {
|
||||
if (src_layer_flag & CD_FLAG_NOCOPY) {
|
||||
/* Don't merge this layer because it's not supposed to leave the source data. */
|
||||
continue;
|
||||
}
|
||||
if (!(mask & CD_TYPE_AS_MASK(type))) {
|
||||
/* Don't merge this layer because it does not match the type mask. */
|
||||
continue;
|
||||
}
|
||||
if ((maxnumber != -1) && (number >= maxnumber)) {
|
||||
if ((max_current_type_layer_count != -1) &&
|
||||
(current_type_layer_count >= max_current_type_layer_count)) {
|
||||
/* Don't merge this layer because the maximum amount of layers of this type is reached. */
|
||||
continue;
|
||||
}
|
||||
if (CustomData_get_named_layer_index(dest, type, layer->name) != -1) {
|
||||
if (CustomData_get_named_layer_index(dest, type, src_layer.name) != -1) {
|
||||
/* Don't merge this layer because it exists in the destination already. */
|
||||
continue;
|
||||
}
|
||||
|
||||
void *data;
|
||||
switch (alloctype) {
|
||||
case CD_ASSIGN:
|
||||
case CD_REFERENCE:
|
||||
case CD_DUPLICATE:
|
||||
data = layer->data;
|
||||
break;
|
||||
default:
|
||||
data = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((alloctype == CD_ASSIGN) && (flag & CD_FLAG_NOFREE)) {
|
||||
newlayer = customData_add_layer__internal(
|
||||
dest, type, CD_REFERENCE, data, totelem, layer->name);
|
||||
}
|
||||
else {
|
||||
newlayer = customData_add_layer__internal(dest, type, alloctype, data, totelem, layer->name);
|
||||
}
|
||||
|
||||
if (newlayer) {
|
||||
newlayer->uid = layer->uid;
|
||||
|
||||
newlayer->active = lastactive;
|
||||
newlayer->active_rnd = lastrender;
|
||||
newlayer->active_clone = lastclone;
|
||||
newlayer->active_mask = lastmask;
|
||||
newlayer->flag |= flag & (CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY);
|
||||
changed = true;
|
||||
|
||||
if (layer->anonymous_id != nullptr) {
|
||||
newlayer->anonymous_id = layer->anonymous_id;
|
||||
if (alloctype == CD_ASSIGN) {
|
||||
layer->anonymous_id = nullptr;
|
||||
void *layer_data_to_assign = nullptr;
|
||||
const ImplicitSharingInfo *sharing_info_to_assign = nullptr;
|
||||
if (!alloctype.has_value()) {
|
||||
if (src_layer.data != nullptr) {
|
||||
if (src_layer.sharing_info == nullptr) {
|
||||
/* Can't share the layer, duplicate it instead. */
|
||||
layer_data_to_assign = copy_layer_data(type, src_layer.data, totelem);
|
||||
}
|
||||
else {
|
||||
layer->anonymous_id->add_user();
|
||||
/* Share the layer. */
|
||||
layer_data_to_assign = src_layer.data;
|
||||
sharing_info_to_assign = src_layer.sharing_info;
|
||||
}
|
||||
}
|
||||
if (alloctype == CD_ASSIGN) {
|
||||
layer->data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CustomDataLayer *new_layer = customData_add_layer__internal(dest,
|
||||
type,
|
||||
alloctype,
|
||||
layer_data_to_assign,
|
||||
sharing_info_to_assign,
|
||||
totelem,
|
||||
src_layer.name);
|
||||
|
||||
new_layer->uid = src_layer.uid;
|
||||
new_layer->flag |= src_layer_flag & (CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY);
|
||||
new_layer->active = last_active;
|
||||
new_layer->active_rnd = last_render;
|
||||
new_layer->active_clone = last_clone;
|
||||
new_layer->active_mask = last_mask;
|
||||
changed = true;
|
||||
|
||||
if (src_layer.anonymous_id != nullptr) {
|
||||
new_layer->anonymous_id = src_layer.anonymous_id;
|
||||
new_layer->anonymous_id->add_user();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2286,6 +2309,23 @@ bool CustomData_merge(const CustomData *source,
|
|||
return changed;
|
||||
}
|
||||
|
||||
bool CustomData_merge(const CustomData *source,
|
||||
CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
int totelem)
|
||||
{
|
||||
return customdata_merge_internal(source, dest, mask, std::nullopt, totelem);
|
||||
}
|
||||
|
||||
bool CustomData_merge_layout(const CustomData *source,
|
||||
CustomData *dest,
|
||||
const eCustomDataMask mask,
|
||||
const eCDAllocType alloctype,
|
||||
const int totelem)
|
||||
{
|
||||
return customdata_merge_internal(source, dest, mask, alloctype, totelem);
|
||||
}
|
||||
|
||||
CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src,
|
||||
const eCustomDataMask mask)
|
||||
{
|
||||
|
@ -2311,28 +2351,91 @@ CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData
|
|||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* An #ImplicitSharingInfo that knows how to free the entire referenced custom data layer
|
||||
* (including potentially separately allocated chunks like for vertex groups).
|
||||
*/
|
||||
class CustomDataLayerImplicitSharing : public ImplicitSharingInfo {
|
||||
private:
|
||||
const void *data_;
|
||||
const int totelem_;
|
||||
const eCustomDataType type_;
|
||||
|
||||
public:
|
||||
CustomDataLayerImplicitSharing(const void *data, const int totelem, const eCustomDataType type)
|
||||
: ImplicitSharingInfo(1), data_(data), totelem_(totelem), type_(type)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void delete_self_with_data() override
|
||||
{
|
||||
free_layer_data(type_, data_, totelem_);
|
||||
MEM_delete(this);
|
||||
}
|
||||
};
|
||||
|
||||
/** Create a #ImplicitSharingInfo that takes ownership of the data. */
|
||||
static ImplicitSharingInfo *make_implicit_sharing_info_for_layer(const eCustomDataType type,
|
||||
const void *data,
|
||||
const int totelem)
|
||||
{
|
||||
return MEM_new<CustomDataLayerImplicitSharing>(__func__, data, totelem, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the layer data is currently shared (hence it is immutable), create a copy that can be edited.
|
||||
*/
|
||||
static void ensure_layer_data_is_mutable(CustomDataLayer &layer, const int totelem)
|
||||
{
|
||||
if (layer.data == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (layer.sharing_info == nullptr) {
|
||||
/* Can not be shared without implicit-sharing data. */
|
||||
return;
|
||||
}
|
||||
if (layer.sharing_info->is_shared()) {
|
||||
const eCustomDataType type = eCustomDataType(layer.type);
|
||||
const void *old_data = layer.data;
|
||||
/* Copy the layer before removing the user because otherwise the data might be freed while
|
||||
* we're still copying from it here. */
|
||||
layer.data = copy_layer_data(type, old_data, totelem);
|
||||
layer.sharing_info->remove_user_and_delete_if_last();
|
||||
layer.sharing_info = make_implicit_sharing_info_for_layer(type, layer.data, totelem);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomData_realloc(CustomData *data, const int old_size, const int new_size)
|
||||
{
|
||||
BLI_assert(new_size >= 0);
|
||||
for (int i = 0; i < data->totlayer; i++) {
|
||||
CustomDataLayer *layer = &data->layers[i];
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(layer->type));
|
||||
|
||||
const int64_t old_size_in_bytes = int64_t(old_size) * typeInfo->size;
|
||||
const int64_t new_size_in_bytes = int64_t(new_size) * typeInfo->size;
|
||||
if (layer->flag & CD_FLAG_NOFREE) {
|
||||
const void *old_data = layer->data;
|
||||
layer->data = MEM_malloc_arrayN(new_size, typeInfo->size, __func__);
|
||||
|
||||
void *new_layer_data = MEM_mallocN(new_size_in_bytes, __func__);
|
||||
/* Copy data to new array. */
|
||||
if (old_size_in_bytes) {
|
||||
if (typeInfo->copy) {
|
||||
typeInfo->copy(old_data, layer->data, std::min(old_size, new_size));
|
||||
typeInfo->copy(layer->data, new_layer_data, std::min(old_size, new_size));
|
||||
}
|
||||
else {
|
||||
std::memcpy(layer->data, old_data, std::min(old_size_in_bytes, new_size_in_bytes));
|
||||
BLI_assert(layer->data != nullptr);
|
||||
memcpy(new_layer_data, layer->data, std::min(old_size_in_bytes, new_size_in_bytes));
|
||||
}
|
||||
layer->flag &= ~CD_FLAG_NOFREE;
|
||||
}
|
||||
else {
|
||||
layer->data = MEM_reallocN(layer->data, new_size_in_bytes);
|
||||
/* Remove ownership of old array */
|
||||
if (layer->sharing_info) {
|
||||
layer->sharing_info->remove_user_and_delete_if_last();
|
||||
layer->sharing_info = nullptr;
|
||||
}
|
||||
/* Take ownership of new array. */
|
||||
layer->data = new_layer_data;
|
||||
if (layer->data) {
|
||||
layer->sharing_info = make_implicit_sharing_info_for_layer(
|
||||
eCustomDataType(layer->type), layer->data, new_size);
|
||||
}
|
||||
|
||||
if (new_size > old_size) {
|
||||
|
@ -2345,11 +2448,7 @@ void CustomData_realloc(CustomData *data, const int old_size, const int new_size
|
|||
}
|
||||
}
|
||||
|
||||
void CustomData_copy(const CustomData *source,
|
||||
CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
eCDAllocType alloctype,
|
||||
int totelem)
|
||||
void CustomData_copy(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
|
||||
{
|
||||
CustomData_reset(dest);
|
||||
|
||||
|
@ -2357,28 +2456,40 @@ void CustomData_copy(const CustomData *source,
|
|||
dest->external = static_cast<CustomDataExternal *>(MEM_dupallocN(source->external));
|
||||
}
|
||||
|
||||
CustomData_merge(source, dest, mask, alloctype, totelem);
|
||||
CustomData_merge(source, dest, mask, totelem);
|
||||
}
|
||||
|
||||
void CustomData_copy_layout(const struct CustomData *source,
|
||||
struct CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
eCDAllocType alloctype,
|
||||
int totelem)
|
||||
{
|
||||
CustomData_reset(dest);
|
||||
|
||||
if (source->external) {
|
||||
dest->external = static_cast<CustomDataExternal *>(MEM_dupallocN(source->external));
|
||||
}
|
||||
|
||||
CustomData_merge_layout(source, dest, mask, alloctype, totelem);
|
||||
}
|
||||
|
||||
static void customData_free_layer__internal(CustomDataLayer *layer, const int totelem)
|
||||
{
|
||||
const LayerTypeInfo *typeInfo;
|
||||
|
||||
if (layer->anonymous_id != nullptr) {
|
||||
layer->anonymous_id->remove_user_and_delete_if_last();
|
||||
layer->anonymous_id = nullptr;
|
||||
}
|
||||
if (!(layer->flag & CD_FLAG_NOFREE) && layer->data) {
|
||||
typeInfo = layerType_getInfo(eCustomDataType(layer->type));
|
||||
|
||||
if (typeInfo->free) {
|
||||
typeInfo->free(layer->data, totelem, typeInfo->size);
|
||||
}
|
||||
|
||||
const eCustomDataType type = eCustomDataType(layer->type);
|
||||
if (layer->sharing_info == nullptr) {
|
||||
if (layer->data) {
|
||||
MEM_freeN(layer->data);
|
||||
free_layer_data(type, layer->data, totelem);
|
||||
}
|
||||
}
|
||||
else {
|
||||
layer->sharing_info->remove_user_and_delete_if_last();
|
||||
layer->sharing_info = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void CustomData_external_free(CustomData *data)
|
||||
|
@ -2738,76 +2849,26 @@ static void customData_resize(CustomData *data, const int grow_amount)
|
|||
data->maxlayer += grow_amount;
|
||||
}
|
||||
|
||||
static CustomDataLayer *customData_add_layer__internal(CustomData *data,
|
||||
const eCustomDataType type,
|
||||
const eCDAllocType alloctype,
|
||||
void *layerdata,
|
||||
const int totelem,
|
||||
const char *name)
|
||||
static CustomDataLayer *customData_add_layer__internal(
|
||||
CustomData *data,
|
||||
const eCustomDataType type,
|
||||
const std::optional<eCDAllocType> alloctype,
|
||||
void *layer_data_to_assign,
|
||||
const ImplicitSharingInfo *sharing_info_to_assign,
|
||||
const int totelem,
|
||||
const char *name)
|
||||
{
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
|
||||
const LayerTypeInfo &type_info = *layerType_getInfo(type);
|
||||
int flag = 0;
|
||||
|
||||
/* Some layer types only support a single layer. */
|
||||
if (!typeInfo->defaultname && CustomData_has_layer(data, type)) {
|
||||
if (!type_info.defaultname && CustomData_has_layer(data, type)) {
|
||||
/* This function doesn't support dealing with existing layer data for these layer types when
|
||||
* the layer already exists. */
|
||||
BLI_assert(layerdata == nullptr);
|
||||
BLI_assert(layer_data_to_assign == nullptr);
|
||||
return &data->layers[CustomData_get_layer_index(data, type)];
|
||||
}
|
||||
|
||||
void *newlayerdata = nullptr;
|
||||
switch (alloctype) {
|
||||
case CD_SET_DEFAULT:
|
||||
if (totelem > 0) {
|
||||
if (typeInfo->set_default_value) {
|
||||
newlayerdata = MEM_malloc_arrayN(totelem, typeInfo->size, layerType_getName(type));
|
||||
typeInfo->set_default_value(newlayerdata, totelem);
|
||||
}
|
||||
else {
|
||||
newlayerdata = MEM_calloc_arrayN(totelem, typeInfo->size, layerType_getName(type));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CD_CONSTRUCT:
|
||||
if (totelem > 0) {
|
||||
newlayerdata = MEM_malloc_arrayN(totelem, typeInfo->size, layerType_getName(type));
|
||||
if (typeInfo->construct) {
|
||||
typeInfo->construct(newlayerdata, totelem);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CD_ASSIGN:
|
||||
if (totelem > 0) {
|
||||
BLI_assert(layerdata != nullptr);
|
||||
newlayerdata = layerdata;
|
||||
}
|
||||
else {
|
||||
MEM_SAFE_FREE(layerdata);
|
||||
}
|
||||
break;
|
||||
case CD_REFERENCE:
|
||||
if (totelem > 0) {
|
||||
BLI_assert(layerdata != nullptr);
|
||||
newlayerdata = layerdata;
|
||||
flag |= CD_FLAG_NOFREE;
|
||||
}
|
||||
break;
|
||||
case CD_DUPLICATE:
|
||||
if (totelem > 0) {
|
||||
newlayerdata = MEM_malloc_arrayN(totelem, typeInfo->size, layerType_getName(type));
|
||||
if (typeInfo->copy) {
|
||||
typeInfo->copy(layerdata, newlayerdata, totelem);
|
||||
}
|
||||
else {
|
||||
BLI_assert(layerdata != nullptr);
|
||||
BLI_assert(newlayerdata != nullptr);
|
||||
memcpy(newlayerdata, layerdata, totelem * typeInfo->size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int index = data->totlayer;
|
||||
if (index >= data->maxlayer) {
|
||||
customData_resize(data, CUSTOMDATA_GROW);
|
||||
|
@ -2815,7 +2876,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
|
|||
|
||||
data->totlayer++;
|
||||
|
||||
/* keep layers ordered by type */
|
||||
/* Keep layers ordered by type. */
|
||||
for (; index > 0 && data->layers[index - 1].type > type; index--) {
|
||||
data->layers[index] = data->layers[index - 1];
|
||||
}
|
||||
|
@ -2827,15 +2888,57 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
|
|||
* leaks into the new layer. */
|
||||
memset(&new_layer, 0, sizeof(CustomDataLayer));
|
||||
|
||||
if (alloctype.has_value()) {
|
||||
switch (*alloctype) {
|
||||
case CD_SET_DEFAULT: {
|
||||
if (totelem > 0) {
|
||||
if (type_info.set_default_value) {
|
||||
new_layer.data = MEM_malloc_arrayN(totelem, type_info.size, layerType_getName(type));
|
||||
type_info.set_default_value(new_layer.data, totelem);
|
||||
}
|
||||
else {
|
||||
new_layer.data = MEM_calloc_arrayN(totelem, type_info.size, layerType_getName(type));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CD_CONSTRUCT: {
|
||||
if (totelem > 0) {
|
||||
new_layer.data = MEM_malloc_arrayN(totelem, type_info.size, layerType_getName(type));
|
||||
if (type_info.construct) {
|
||||
type_info.construct(new_layer.data, totelem);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (totelem == 0 && sharing_info_to_assign == nullptr) {
|
||||
MEM_SAFE_FREE(layer_data_to_assign);
|
||||
}
|
||||
else {
|
||||
new_layer.data = layer_data_to_assign;
|
||||
new_layer.sharing_info = sharing_info_to_assign;
|
||||
if (new_layer.sharing_info) {
|
||||
new_layer.sharing_info->add_user();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (new_layer.data != nullptr && new_layer.sharing_info == nullptr) {
|
||||
/* Make layer data shareable. */
|
||||
new_layer.sharing_info = make_implicit_sharing_info_for_layer(type, new_layer.data, totelem);
|
||||
}
|
||||
|
||||
new_layer.type = type;
|
||||
new_layer.flag = flag;
|
||||
new_layer.data = newlayerdata;
|
||||
|
||||
/* Set default name if none exists. Note we only call DATA_() once
|
||||
* we know there is a default name, to avoid overhead of locale lookups
|
||||
* in the depsgraph. */
|
||||
if (!name && typeInfo->defaultname) {
|
||||
name = DATA_(typeInfo->defaultname);
|
||||
if (!name && type_info.defaultname) {
|
||||
name = DATA_(type_info.defaultname);
|
||||
}
|
||||
|
||||
if (name) {
|
||||
|
@ -2864,16 +2967,15 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
|
|||
return &data->layers[index];
|
||||
}
|
||||
|
||||
static void *customdata_add_layer(CustomData *data,
|
||||
const eCustomDataType type,
|
||||
eCDAllocType alloctype,
|
||||
void *layerdata,
|
||||
const int totelem)
|
||||
void *CustomData_add_layer(CustomData *data,
|
||||
const eCustomDataType type,
|
||||
eCDAllocType alloctype,
|
||||
const int totelem)
|
||||
{
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
|
||||
|
||||
CustomDataLayer *layer = customData_add_layer__internal(
|
||||
data, type, alloctype, layerdata, totelem, typeInfo->defaultname);
|
||||
data, type, alloctype, nullptr, nullptr, totelem, typeInfo->defaultname);
|
||||
CustomData_update_typemap(data);
|
||||
|
||||
if (layer) {
|
||||
|
@ -2883,31 +2985,16 @@ static void *customdata_add_layer(CustomData *data,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void *CustomData_add_layer(CustomData *data,
|
||||
const eCustomDataType type,
|
||||
const eCDAllocType alloctype,
|
||||
const int totelem)
|
||||
{
|
||||
return customdata_add_layer(data, type, alloctype, nullptr, totelem);
|
||||
}
|
||||
|
||||
const void *CustomData_add_layer_with_data(CustomData *data,
|
||||
const eCustomDataType type,
|
||||
void *layer_data,
|
||||
const int totelem)
|
||||
const int totelem,
|
||||
const ImplicitSharingInfo *sharing_info)
|
||||
{
|
||||
return customdata_add_layer(data, type, CD_ASSIGN, layer_data, totelem);
|
||||
}
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
|
||||
|
||||
static void *customdata_add_layer_named(CustomData *data,
|
||||
const eCustomDataType type,
|
||||
const eCDAllocType alloctype,
|
||||
void *layerdata,
|
||||
const int totelem,
|
||||
const char *name)
|
||||
{
|
||||
CustomDataLayer *layer = customData_add_layer__internal(
|
||||
data, type, alloctype, layerdata, totelem, name);
|
||||
data, type, std::nullopt, layer_data, sharing_info, totelem, typeInfo->defaultname);
|
||||
CustomData_update_typemap(data);
|
||||
|
||||
if (layer) {
|
||||
|
@ -2923,25 +3010,42 @@ void *CustomData_add_layer_named(CustomData *data,
|
|||
const int totelem,
|
||||
const char *name)
|
||||
{
|
||||
return customdata_add_layer_named(data, type, alloctype, nullptr, totelem, name);
|
||||
CustomDataLayer *layer = customData_add_layer__internal(
|
||||
data, type, alloctype, nullptr, nullptr, totelem, name);
|
||||
CustomData_update_typemap(data);
|
||||
|
||||
if (layer) {
|
||||
return layer->data;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const void *CustomData_add_layer_named_with_data(
|
||||
CustomData *data, const eCustomDataType type, void *layer_data, int totelem, const char *name)
|
||||
const void *CustomData_add_layer_named_with_data(CustomData *data,
|
||||
eCustomDataType type,
|
||||
void *layer_data,
|
||||
int totelem,
|
||||
const char *name,
|
||||
const ImplicitSharingInfo *sharing_info)
|
||||
{
|
||||
return customdata_add_layer_named(data, type, CD_ASSIGN, layer_data, totelem, name);
|
||||
CustomDataLayer *layer = customData_add_layer__internal(
|
||||
data, type, std::nullopt, layer_data, sharing_info, totelem, name);
|
||||
CustomData_update_typemap(data);
|
||||
|
||||
if (layer) {
|
||||
return layer->data;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *CustomData_add_layer_anonymous(CustomData *data,
|
||||
const eCustomDataType type,
|
||||
const eCDAllocType alloctype,
|
||||
void *layerdata,
|
||||
const int totelem,
|
||||
const AnonymousAttributeIDHandle *anonymous_id)
|
||||
{
|
||||
const char *name = anonymous_id->name().c_str();
|
||||
CustomDataLayer *layer = customData_add_layer__internal(
|
||||
data, type, alloctype, layerdata, totelem, name);
|
||||
data, type, alloctype, nullptr, nullptr, totelem, name);
|
||||
CustomData_update_typemap(data);
|
||||
|
||||
if (layer == nullptr) {
|
||||
|
@ -2953,6 +3057,27 @@ void *CustomData_add_layer_anonymous(CustomData *data,
|
|||
return layer->data;
|
||||
}
|
||||
|
||||
const void *CustomData_add_layer_anonymous_with_data(
|
||||
CustomData *data,
|
||||
const eCustomDataType type,
|
||||
const AnonymousAttributeIDHandle *anonymous_id,
|
||||
const int totelem,
|
||||
void *layer_data,
|
||||
const ImplicitSharingInfo *sharing_info)
|
||||
{
|
||||
const char *name = anonymous_id->name().c_str();
|
||||
CustomDataLayer *layer = customData_add_layer__internal(
|
||||
data, type, std::nullopt, layer_data, sharing_info, totelem, name);
|
||||
CustomData_update_typemap(data);
|
||||
|
||||
if (layer == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
anonymous_id->add_user();
|
||||
layer->anonymous_id = anonymous_id;
|
||||
return layer->data;
|
||||
}
|
||||
|
||||
bool CustomData_free_layer(CustomData *data,
|
||||
const eCustomDataType type,
|
||||
const int totelem,
|
||||
|
@ -3081,47 +3206,6 @@ int CustomData_number_of_layers_typemask(const CustomData *data, const eCustomDa
|
|||
return number;
|
||||
}
|
||||
|
||||
static void *customData_duplicate_referenced_layer_index(CustomData *data,
|
||||
const int layer_index,
|
||||
const int totelem)
|
||||
{
|
||||
if (layer_index == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CustomDataLayer *layer = &data->layers[layer_index];
|
||||
|
||||
if (layer->flag & CD_FLAG_NOFREE) {
|
||||
/* MEM_dupallocN won't work in case of complex layers, like e.g.
|
||||
* CD_MDEFORMVERT, which has pointers to allocated data...
|
||||
* So in case a custom copy function is defined, use it!
|
||||
*/
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(layer->type));
|
||||
|
||||
if (typeInfo->copy) {
|
||||
void *dst_data = MEM_malloc_arrayN(
|
||||
size_t(totelem), typeInfo->size, "CD duplicate ref layer");
|
||||
typeInfo->copy(layer->data, dst_data, totelem);
|
||||
layer->data = dst_data;
|
||||
}
|
||||
else {
|
||||
layer->data = MEM_dupallocN(layer->data);
|
||||
}
|
||||
|
||||
layer->flag &= ~CD_FLAG_NOFREE;
|
||||
}
|
||||
|
||||
return layer->data;
|
||||
}
|
||||
|
||||
void CustomData_duplicate_referenced_layers(CustomData *data, const int totelem)
|
||||
{
|
||||
for (int i = 0; i < data->totlayer; i++) {
|
||||
CustomDataLayer *layer = &data->layers[i];
|
||||
layer->data = customData_duplicate_referenced_layer_index(data, i, totelem);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomData_free_temporary(CustomData *data, const int totelem)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -3299,14 +3383,12 @@ void CustomData_copy_layer_type_data(const CustomData *source,
|
|||
void CustomData_free_elem(CustomData *data, const int index, const int count)
|
||||
{
|
||||
for (int i = 0; i < data->totlayer; i++) {
|
||||
if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
|
||||
|
||||
if (typeInfo->free) {
|
||||
size_t offset = size_t(index) * typeInfo->size;
|
||||
if (typeInfo->free) {
|
||||
size_t offset = size_t(index) * typeInfo->size;
|
||||
|
||||
typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size);
|
||||
}
|
||||
typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3476,7 +3558,12 @@ void *CustomData_get_layer_for_write(CustomData *data,
|
|||
const int totelem)
|
||||
{
|
||||
const int layer_index = CustomData_get_active_layer_index(data, type);
|
||||
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
|
||||
if (layer_index == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
CustomDataLayer &layer = data->layers[layer_index];
|
||||
ensure_layer_data_is_mutable(layer, totelem);
|
||||
return layer.data;
|
||||
}
|
||||
|
||||
const void *CustomData_get_layer_n(const CustomData *data, const eCustomDataType type, const int n)
|
||||
|
@ -3485,7 +3572,6 @@ const void *CustomData_get_layer_n(const CustomData *data, const eCustomDataType
|
|||
if (layer_index == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return data->layers[layer_index].data;
|
||||
}
|
||||
|
||||
|
@ -3495,7 +3581,12 @@ void *CustomData_get_layer_n_for_write(CustomData *data,
|
|||
const int totelem)
|
||||
{
|
||||
const int layer_index = CustomData_get_layer_index_n(data, type, n);
|
||||
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
|
||||
if (layer_index == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
CustomDataLayer &layer = data->layers[layer_index];
|
||||
ensure_layer_data_is_mutable(layer, totelem);
|
||||
return layer.data;
|
||||
}
|
||||
|
||||
const void *CustomData_get_layer_named(const CustomData *data,
|
||||
|
@ -3506,7 +3597,6 @@ const void *CustomData_get_layer_named(const CustomData *data,
|
|||
if (layer_index == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return data->layers[layer_index].data;
|
||||
}
|
||||
|
||||
|
@ -3516,7 +3606,12 @@ void *CustomData_get_layer_named_for_write(CustomData *data,
|
|||
const int totelem)
|
||||
{
|
||||
const int layer_index = CustomData_get_named_layer_index(data, type, name);
|
||||
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
|
||||
if (layer_index == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
CustomDataLayer &layer = data->layers[layer_index];
|
||||
ensure_layer_data_is_mutable(layer, totelem);
|
||||
return layer.data;
|
||||
}
|
||||
|
||||
int CustomData_get_offset(const CustomData *data, const eCustomDataType type)
|
||||
|
@ -3525,7 +3620,6 @@ int CustomData_get_offset(const CustomData *data, const eCustomDataType type)
|
|||
if (layer_index == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return data->layers[layer_index].offset;
|
||||
}
|
||||
|
||||
|
@ -3610,12 +3704,12 @@ void CustomData_bmesh_init_pool(CustomData *data, const int totelem, const char
|
|||
}
|
||||
}
|
||||
|
||||
bool CustomData_bmesh_merge(const CustomData *source,
|
||||
CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
eCDAllocType alloctype,
|
||||
BMesh *bm,
|
||||
const char htype)
|
||||
bool CustomData_bmesh_merge_layout(const CustomData *source,
|
||||
CustomData *dest,
|
||||
eCustomDataMask mask,
|
||||
eCDAllocType alloctype,
|
||||
BMesh *bm,
|
||||
const char htype)
|
||||
{
|
||||
|
||||
if (CustomData_number_of_layers_typemask(source, mask) == 0) {
|
||||
|
@ -3629,7 +3723,7 @@ bool CustomData_bmesh_merge(const CustomData *source,
|
|||
destold.layers = static_cast<CustomDataLayer *>(MEM_dupallocN(destold.layers));
|
||||
}
|
||||
|
||||
if (CustomData_merge(source, dest, mask, alloctype, 0) == false) {
|
||||
if (CustomData_merge_layout(source, dest, mask, alloctype, 0) == false) {
|
||||
if (destold.layers) {
|
||||
MEM_freeN(destold.layers);
|
||||
}
|
||||
|
@ -3709,13 +3803,11 @@ void CustomData_bmesh_free_block(CustomData *data, void **block)
|
|||
}
|
||||
|
||||
for (int i = 0; i < data->totlayer; i++) {
|
||||
if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
|
||||
|
||||
if (typeInfo->free) {
|
||||
int offset = data->layers[i].offset;
|
||||
typeInfo->free(POINTER_OFFSET(*block, offset), 1, typeInfo->size);
|
||||
}
|
||||
if (typeInfo->free) {
|
||||
int offset = data->layers[i].offset;
|
||||
typeInfo->free(POINTER_OFFSET(*block, offset), 1, typeInfo->size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3732,12 +3824,10 @@ void CustomData_bmesh_free_block_data(CustomData *data, void *block)
|
|||
return;
|
||||
}
|
||||
for (int i = 0; i < data->totlayer; i++) {
|
||||
if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
|
||||
if (typeInfo->free) {
|
||||
const size_t offset = data->layers[i].offset;
|
||||
typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
|
||||
}
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
|
||||
if (typeInfo->free) {
|
||||
const size_t offset = data->layers[i].offset;
|
||||
typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
|
||||
}
|
||||
}
|
||||
if (data->totsize) {
|
||||
|
@ -3770,10 +3860,8 @@ void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data,
|
|||
if ((CD_TYPE_AS_MASK(data->layers[i].type) & mask_exclude) == 0) {
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
|
||||
const size_t offset = data->layers[i].offset;
|
||||
if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
|
||||
if (typeInfo->free) {
|
||||
typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
|
||||
}
|
||||
if (typeInfo->free) {
|
||||
typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
|
||||
}
|
||||
memset(POINTER_OFFSET(block, offset), 0, typeInfo->size);
|
||||
}
|
||||
|
@ -3951,11 +4039,9 @@ bool CustomData_has_math(const CustomData *data)
|
|||
bool CustomData_bmesh_has_free(const CustomData *data)
|
||||
{
|
||||
for (int i = 0; i < data->totlayer; i++) {
|
||||
if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
|
||||
if (typeInfo->free) {
|
||||
return true;
|
||||
}
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
|
||||
if (typeInfo->free) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -3973,16 +4059,6 @@ bool CustomData_has_interp(const CustomData *data)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CustomData_has_referenced(const CustomData *data)
|
||||
{
|
||||
for (int i = 0; i < data->totlayer; i++) {
|
||||
if (data->layers[i].flag & CD_FLAG_NOFREE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CustomData_data_copy_value(const eCustomDataType type, const void *source, void *dest)
|
||||
{
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
|
||||
|
@ -5188,11 +5264,15 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, const int
|
|||
if (layer->flag & CD_FLAG_EXTERNAL) {
|
||||
layer->flag &= ~CD_FLAG_IN_MEMORY;
|
||||
}
|
||||
|
||||
layer->flag &= ~CD_FLAG_NOFREE;
|
||||
layer->sharing_info = nullptr;
|
||||
|
||||
if (CustomData_verify_versions(data, i)) {
|
||||
BLO_read_data_address(reader, &layer->data);
|
||||
if (layer->data != nullptr) {
|
||||
/* Make layer data shareable. */
|
||||
layer->sharing_info = make_implicit_sharing_info_for_layer(
|
||||
eCustomDataType(layer->type), layer->data, count);
|
||||
}
|
||||
if (CustomData_layer_ensure_data_exists(layer, count)) {
|
||||
/* Under normal operations, this shouldn't happen, but...
|
||||
* For a CD_PROP_BOOL example, see #84935.
|
||||
|
|
|
@ -72,7 +72,6 @@ using blender::StringRef;
|
|||
using blender::VArray;
|
||||
using blender::Vector;
|
||||
|
||||
static void mesh_clear_geometry(Mesh *mesh);
|
||||
static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata);
|
||||
|
||||
static void mesh_init_data(ID *id)
|
||||
|
@ -151,14 +150,13 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
|
|||
mesh_dst->default_color_attribute = static_cast<char *>(
|
||||
MEM_dupallocN(mesh_src->default_color_attribute));
|
||||
|
||||
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
|
||||
CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, alloc_type, mesh_dst->totvert);
|
||||
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, alloc_type, mesh_dst->totedge);
|
||||
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, alloc_type, mesh_dst->totloop);
|
||||
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, alloc_type, mesh_dst->totpoly);
|
||||
CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, mesh_dst->totvert);
|
||||
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, mesh_dst->totedge);
|
||||
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, mesh_dst->totloop);
|
||||
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, mesh_dst->totpoly);
|
||||
mesh_dst->poly_offset_indices = static_cast<int *>(MEM_dupallocN(mesh_src->poly_offset_indices));
|
||||
if (do_tessface) {
|
||||
CustomData_copy(&mesh_src->fdata, &mesh_dst->fdata, mask.fmask, alloc_type, mesh_dst->totface);
|
||||
CustomData_copy(&mesh_src->fdata, &mesh_dst->fdata, mask.fmask, mesh_dst->totface);
|
||||
}
|
||||
else {
|
||||
mesh_tessface_clear_intern(mesh_dst, false);
|
||||
|
@ -193,11 +191,9 @@ static void mesh_free_data(ID *id)
|
|||
{
|
||||
Mesh *mesh = (Mesh *)id;
|
||||
|
||||
BLI_freelistN(&mesh->vertex_group_names);
|
||||
|
||||
BKE_mesh_free_editmesh(mesh);
|
||||
|
||||
mesh_clear_geometry(mesh);
|
||||
BKE_mesh_clear_geometry_and_metadata(mesh);
|
||||
MEM_SAFE_FREE(mesh->mat);
|
||||
|
||||
delete mesh->runtime;
|
||||
|
@ -526,9 +522,9 @@ static bool is_sublayer_name(char const *sublayer_name, char const *name)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool is_uv_bool_sublayer(CustomDataLayer const *l)
|
||||
static bool is_uv_bool_sublayer(const CustomDataLayer &layer)
|
||||
{
|
||||
char const *name = l->name;
|
||||
char const *name = layer.name;
|
||||
|
||||
if (name[0] != '.') {
|
||||
return false;
|
||||
|
@ -557,7 +553,7 @@ static int customdata_compare(
|
|||
for (int i = 0; i < c1->totlayer; i++) {
|
||||
l1 = &c1->layers[i];
|
||||
if ((CD_TYPE_AS_MASK(l1->type) & cd_mask_all_attr) && l1->anonymous_id == nullptr &&
|
||||
!is_uv_bool_sublayer(l1)) {
|
||||
!is_uv_bool_sublayer(*l1)) {
|
||||
layer_count1++;
|
||||
}
|
||||
}
|
||||
|
@ -565,7 +561,7 @@ static int customdata_compare(
|
|||
for (int i = 0; i < c2->totlayer; i++) {
|
||||
l2 = &c2->layers[i];
|
||||
if ((CD_TYPE_AS_MASK(l2->type) & cd_mask_all_attr) && l2->anonymous_id == nullptr &&
|
||||
!is_uv_bool_sublayer(l2)) {
|
||||
!is_uv_bool_sublayer(*l2)) {
|
||||
layer_count2++;
|
||||
}
|
||||
}
|
||||
|
@ -581,7 +577,7 @@ static int customdata_compare(
|
|||
|
||||
for (int i1 = 0; i1 < c1->totlayer; i1++) {
|
||||
l1 = c1->layers + i1;
|
||||
if (l1->anonymous_id != nullptr || is_uv_bool_sublayer(l1)) {
|
||||
if (l1->anonymous_id != nullptr || is_uv_bool_sublayer(*l1)) {
|
||||
continue;
|
||||
}
|
||||
bool found_corresponding_layer = false;
|
||||
|
@ -905,37 +901,47 @@ void BKE_mesh_free_data_for_undo(Mesh *me)
|
|||
* Material slots should be kept in sync with the object.
|
||||
*
|
||||
* - Edit-Mesh (#Mesh.edit_mesh)
|
||||
* Since edit-mesh is tied to the objects mode,
|
||||
* which crashes when called in edit-mode, see: #90972.
|
||||
* Since edit-mesh is tied to the object's mode, which crashes when called in edit-mode.
|
||||
* See: #90972.
|
||||
*/
|
||||
static void mesh_clear_geometry(Mesh *mesh)
|
||||
static void mesh_clear_geometry(Mesh &mesh)
|
||||
{
|
||||
CustomData_free(&mesh->vdata, mesh->totvert);
|
||||
CustomData_free(&mesh->edata, mesh->totedge);
|
||||
CustomData_free(&mesh->fdata, mesh->totface);
|
||||
CustomData_free(&mesh->ldata, mesh->totloop);
|
||||
CustomData_free(&mesh->pdata, mesh->totpoly);
|
||||
MEM_SAFE_FREE(mesh->poly_offset_indices);
|
||||
CustomData_free(&mesh.vdata, mesh.totvert);
|
||||
CustomData_free(&mesh.edata, mesh.totedge);
|
||||
CustomData_free(&mesh.fdata, mesh.totface);
|
||||
CustomData_free(&mesh.ldata, mesh.totloop);
|
||||
CustomData_free(&mesh.pdata, mesh.totpoly);
|
||||
MEM_SAFE_FREE(mesh.poly_offset_indices);
|
||||
|
||||
MEM_SAFE_FREE(mesh->mselect);
|
||||
MEM_SAFE_FREE(mesh.mselect);
|
||||
|
||||
mesh->totvert = 0;
|
||||
mesh->totedge = 0;
|
||||
mesh->totface = 0;
|
||||
mesh->totloop = 0;
|
||||
mesh->totpoly = 0;
|
||||
mesh->act_face = -1;
|
||||
mesh->totselect = 0;
|
||||
mesh.totvert = 0;
|
||||
mesh.totedge = 0;
|
||||
mesh.totface = 0;
|
||||
mesh.totloop = 0;
|
||||
mesh.totpoly = 0;
|
||||
mesh.act_face = -1;
|
||||
mesh.totselect = 0;
|
||||
}
|
||||
|
||||
BLI_freelistN(&mesh->vertex_group_names);
|
||||
MEM_SAFE_FREE(mesh->active_color_attribute);
|
||||
MEM_SAFE_FREE(mesh->default_color_attribute);
|
||||
static void clear_attribute_names(Mesh &mesh)
|
||||
{
|
||||
BLI_freelistN(&mesh.vertex_group_names);
|
||||
MEM_SAFE_FREE(mesh.active_color_attribute);
|
||||
MEM_SAFE_FREE(mesh.default_color_attribute);
|
||||
}
|
||||
|
||||
void BKE_mesh_clear_geometry(Mesh *mesh)
|
||||
{
|
||||
BKE_mesh_runtime_clear_cache(mesh);
|
||||
mesh_clear_geometry(mesh);
|
||||
mesh_clear_geometry(*mesh);
|
||||
}
|
||||
|
||||
void BKE_mesh_clear_geometry_and_metadata(Mesh *mesh)
|
||||
{
|
||||
BKE_mesh_runtime_clear_cache(mesh);
|
||||
mesh_clear_geometry(*mesh);
|
||||
clear_attribute_names(*mesh);
|
||||
}
|
||||
|
||||
static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
|
||||
|
@ -963,34 +969,33 @@ void BKE_mesh_poly_offsets_ensure_alloc(Mesh *mesh)
|
|||
if (mesh->totpoly == 0) {
|
||||
return;
|
||||
}
|
||||
if (!mesh->poly_offset_indices) {
|
||||
mesh->poly_offset_indices = static_cast<int *>(
|
||||
MEM_malloc_arrayN(mesh->totpoly + 1, sizeof(int), __func__));
|
||||
}
|
||||
mesh->poly_offset_indices = static_cast<int *>(
|
||||
MEM_malloc_arrayN(mesh->totpoly + 1, sizeof(int), __func__));
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Fill offsets with obviously bad values to simplify finding missing initialization. */
|
||||
mesh->poly_offsets_for_write().fill(-1);
|
||||
#endif
|
||||
mesh->poly_offsets_for_write().last() = mesh->totloop;
|
||||
mesh->poly_offset_indices[0] = 0;
|
||||
mesh->poly_offset_indices[mesh->totpoly] = mesh->totloop;
|
||||
}
|
||||
|
||||
/* Custom data layer functions; those assume that totXXX are set correctly. */
|
||||
static void mesh_ensure_cdlayers_primary(Mesh *mesh)
|
||||
static void mesh_ensure_cdlayers_primary(Mesh &mesh)
|
||||
{
|
||||
if (!CustomData_get_layer_named(&mesh->vdata, CD_PROP_FLOAT3, "position")) {
|
||||
if (!CustomData_get_layer_named(&mesh.vdata, CD_PROP_FLOAT3, "position")) {
|
||||
CustomData_add_layer_named(
|
||||
&mesh->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, mesh->totvert, "position");
|
||||
&mesh.vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, mesh.totvert, "position");
|
||||
}
|
||||
if (!CustomData_get_layer(&mesh->edata, CD_MEDGE)) {
|
||||
CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_SET_DEFAULT, mesh->totedge);
|
||||
if (!CustomData_get_layer(&mesh.edata, CD_MEDGE)) {
|
||||
CustomData_add_layer(&mesh.edata, CD_MEDGE, CD_SET_DEFAULT, mesh.totedge);
|
||||
}
|
||||
if (!CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_vert")) {
|
||||
if (!CustomData_get_layer_named(&mesh.ldata, CD_PROP_INT32, ".corner_vert")) {
|
||||
CustomData_add_layer_named(
|
||||
&mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, mesh->totloop, ".corner_vert");
|
||||
&mesh.ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh.totloop, ".corner_vert");
|
||||
}
|
||||
if (!CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) {
|
||||
if (!CustomData_get_layer_named(&mesh.ldata, CD_PROP_INT32, ".corner_edge")) {
|
||||
CustomData_add_layer_named(
|
||||
&mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, mesh->totloop, ".corner_edge");
|
||||
&mesh.ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh.totloop, ".corner_edge");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,7 +1017,7 @@ Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int loops_len, int polys
|
|||
mesh->totloop = loops_len;
|
||||
mesh->totpoly = polys_len;
|
||||
|
||||
mesh_ensure_cdlayers_primary(mesh);
|
||||
mesh_ensure_cdlayers_primary(*mesh);
|
||||
BKE_mesh_poly_offsets_ensure_alloc(mesh);
|
||||
|
||||
return mesh;
|
||||
|
@ -1096,12 +1101,13 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
|
|||
|
||||
BKE_mesh_copy_parameters_for_eval(me_dst, me_src);
|
||||
|
||||
CustomData_copy(&me_src->vdata, &me_dst->vdata, mask.vmask, CD_SET_DEFAULT, verts_len);
|
||||
CustomData_copy(&me_src->edata, &me_dst->edata, mask.emask, CD_SET_DEFAULT, edges_len);
|
||||
CustomData_copy(&me_src->ldata, &me_dst->ldata, mask.lmask, CD_SET_DEFAULT, loops_len);
|
||||
CustomData_copy(&me_src->pdata, &me_dst->pdata, mask.pmask, CD_SET_DEFAULT, polys_len);
|
||||
CustomData_copy_layout(&me_src->vdata, &me_dst->vdata, mask.vmask, CD_SET_DEFAULT, verts_len);
|
||||
CustomData_copy_layout(&me_src->edata, &me_dst->edata, mask.emask, CD_SET_DEFAULT, edges_len);
|
||||
CustomData_copy_layout(&me_src->ldata, &me_dst->ldata, mask.lmask, CD_SET_DEFAULT, loops_len);
|
||||
CustomData_copy_layout(&me_src->pdata, &me_dst->pdata, mask.pmask, CD_SET_DEFAULT, polys_len);
|
||||
if (do_tessface) {
|
||||
CustomData_copy(&me_src->fdata, &me_dst->fdata, mask.fmask, CD_SET_DEFAULT, tessface_len);
|
||||
CustomData_copy_layout(
|
||||
&me_src->fdata, &me_dst->fdata, mask.fmask, CD_SET_DEFAULT, tessface_len);
|
||||
}
|
||||
else {
|
||||
mesh_tessface_clear_intern(me_dst, false);
|
||||
|
@ -1109,7 +1115,7 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
|
|||
|
||||
/* The destination mesh should at least have valid primary CD layers,
|
||||
* even in cases where the source mesh does not. */
|
||||
mesh_ensure_cdlayers_primary(me_dst);
|
||||
mesh_ensure_cdlayers_primary(*me_dst);
|
||||
BKE_mesh_poly_offsets_ensure_alloc(me_dst);
|
||||
if (do_tessface && !CustomData_get_layer(&me_dst->fdata, CD_MFACE)) {
|
||||
CustomData_add_layer(&me_dst->fdata, CD_MFACE, CD_SET_DEFAULT, me_dst->totface);
|
||||
|
@ -1378,7 +1384,7 @@ void BKE_mesh_orco_ensure(Object *ob, Mesh *mesh)
|
|||
/* Orcos are stored in normalized 0..1 range by convention. */
|
||||
float(*orcodata)[3] = BKE_mesh_orco_verts_get(ob);
|
||||
BKE_mesh_orco_verts_transform(mesh, orcodata, mesh->totvert, false);
|
||||
CustomData_add_layer_with_data(&mesh->vdata, CD_ORCO, orcodata, mesh->totvert);
|
||||
CustomData_add_layer_with_data(&mesh->vdata, CD_ORCO, orcodata, mesh->totvert, nullptr);
|
||||
}
|
||||
|
||||
Mesh *BKE_mesh_from_object(Object *ob)
|
||||
|
|
|
@ -656,15 +656,15 @@ static void merge_vertex_loop_poly_customdata_layers(Mesh *target, MeshesToIMesh
|
|||
for (int mesh_index = 1; mesh_index < mim.meshes.size(); ++mesh_index) {
|
||||
const Mesh *me = mim.meshes[mesh_index];
|
||||
if (me->totvert) {
|
||||
CustomData_merge(
|
||||
CustomData_merge_layout(
|
||||
&me->vdata, &target->vdata, CD_MASK_MESH.vmask, CD_SET_DEFAULT, target->totvert);
|
||||
}
|
||||
if (me->totloop) {
|
||||
CustomData_merge(
|
||||
CustomData_merge_layout(
|
||||
&me->ldata, &target->ldata, CD_MASK_MESH.lmask, CD_SET_DEFAULT, target->totloop);
|
||||
}
|
||||
if (me->totpoly) {
|
||||
CustomData_merge(
|
||||
CustomData_merge_layout(
|
||||
&me->pdata, &target->pdata, CD_MASK_MESH.pmask, CD_SET_DEFAULT, target->totpoly);
|
||||
}
|
||||
}
|
||||
|
@ -675,7 +675,7 @@ static void merge_edge_customdata_layers(Mesh *target, MeshesToIMeshInfo &mim)
|
|||
for (int mesh_index = 0; mesh_index < mim.meshes.size(); ++mesh_index) {
|
||||
const Mesh *me = mim.meshes[mesh_index];
|
||||
if (me->totedge) {
|
||||
CustomData_merge(
|
||||
CustomData_merge_layout(
|
||||
&me->edata, &target->edata, CD_MASK_MESH.emask, CD_SET_DEFAULT, target->totedge);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,7 +244,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
|
|||
/* Free old CustomData and assign new one. */
|
||||
CustomData_free(&mesh->edata, mesh->totedge);
|
||||
CustomData_reset(&mesh->edata);
|
||||
CustomData_add_layer_with_data(&mesh->edata, CD_MEDGE, new_edges.data(), new_totedge);
|
||||
CustomData_add_layer_with_data(&mesh->edata, CD_MEDGE, new_edges.data(), new_totedge, nullptr);
|
||||
mesh->totedge = new_totedge;
|
||||
|
||||
if (select_new_edges) {
|
||||
|
|
|
@ -625,7 +625,7 @@ void BKE_pointcloud_from_mesh(const Mesh *me, PointCloud *pointcloud)
|
|||
{
|
||||
CustomData_free(&pointcloud->pdata, pointcloud->totpoint);
|
||||
pointcloud->totpoint = me->totvert;
|
||||
CustomData_merge(&me->vdata, &pointcloud->pdata, CD_MASK_PROP_ALL, CD_DUPLICATE, me->totvert);
|
||||
CustomData_merge(&me->vdata, &pointcloud->pdata, CD_MASK_PROP_ALL, me->totvert);
|
||||
}
|
||||
|
||||
void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/, Object *ob)
|
||||
|
@ -652,8 +652,7 @@ void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/
|
|||
void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
|
||||
{
|
||||
me->totvert = pointcloud->totpoint;
|
||||
CustomData_merge(
|
||||
&pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, CD_DUPLICATE, pointcloud->totpoint);
|
||||
CustomData_merge(&pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, pointcloud->totpoint);
|
||||
}
|
||||
|
||||
void BKE_pointcloud_to_mesh(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/, Object *ob)
|
||||
|
@ -1114,14 +1113,7 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
|
|||
BLI_assert(mesh_dst == ob->data);
|
||||
}
|
||||
|
||||
BKE_mesh_clear_geometry(mesh_dst);
|
||||
|
||||
/* Make sure referenced layers have a single user so assigning them to the mesh in main doesn't
|
||||
* share them. "Referenced" layers are not expected to be shared between original meshes. */
|
||||
CustomData_duplicate_referenced_layers(&mesh_src->vdata, mesh_src->totvert);
|
||||
CustomData_duplicate_referenced_layers(&mesh_src->edata, mesh_src->totedge);
|
||||
CustomData_duplicate_referenced_layers(&mesh_src->pdata, mesh_src->totpoly);
|
||||
CustomData_duplicate_referenced_layers(&mesh_src->ldata, mesh_src->totloop);
|
||||
BKE_mesh_clear_geometry_and_metadata(mesh_dst);
|
||||
|
||||
const bool verts_num_changed = mesh_dst->totvert != mesh_src->totvert;
|
||||
mesh_dst->totvert = mesh_src->totvert;
|
||||
|
@ -1131,26 +1123,16 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
|
|||
|
||||
/* Using #CD_MASK_MESH ensures that only data that should exist in Main meshes is moved. */
|
||||
const CustomData_MeshMasks mask = CD_MASK_MESH;
|
||||
CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, CD_ASSIGN, mesh_src->totvert);
|
||||
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, CD_ASSIGN, mesh_src->totedge);
|
||||
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, CD_ASSIGN, mesh_src->totpoly);
|
||||
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, CD_ASSIGN, mesh_src->totloop);
|
||||
mesh_dst->poly_offset_indices = static_cast<int *>(mesh_src->poly_offset_indices);
|
||||
mesh_src->poly_offset_indices = nullptr;
|
||||
CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, mesh_src->totvert);
|
||||
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, mesh_src->totedge);
|
||||
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, mesh_src->totpoly);
|
||||
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, mesh_src->totloop);
|
||||
std::swap(mesh_dst->poly_offset_indices, mesh_src->poly_offset_indices);
|
||||
|
||||
/* Make sure active/default color attribute (names) are brought over. */
|
||||
if (mesh_src->active_color_attribute) {
|
||||
MEM_SAFE_FREE(mesh_dst->active_color_attribute);
|
||||
mesh_dst->active_color_attribute = BLI_strdup(mesh_src->active_color_attribute);
|
||||
}
|
||||
if (mesh_src->default_color_attribute) {
|
||||
MEM_SAFE_FREE(mesh_dst->default_color_attribute);
|
||||
mesh_dst->default_color_attribute = BLI_strdup(mesh_src->default_color_attribute);
|
||||
}
|
||||
|
||||
BLI_freelistN(&mesh_dst->vertex_group_names);
|
||||
mesh_dst->vertex_group_names = mesh_src->vertex_group_names;
|
||||
BLI_listbase_clear(&mesh_src->vertex_group_names);
|
||||
/* Make sure attribute names are moved. */
|
||||
std::swap(mesh_dst->active_color_attribute, mesh_src->active_color_attribute);
|
||||
std::swap(mesh_dst->default_color_attribute, mesh_src->default_color_attribute);
|
||||
std::swap(mesh_dst->vertex_group_names, mesh_src->vertex_group_names);
|
||||
|
||||
BKE_mesh_copy_parameters(mesh_dst, mesh_src);
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ void BKE_mesh_calc_edges_legacy(Mesh *me)
|
|||
return;
|
||||
}
|
||||
|
||||
edges = (MEdge *)CustomData_add_layer_with_data(&me->edata, CD_MEDGE, edges, totedge);
|
||||
edges = (MEdge *)CustomData_add_layer_with_data(&me->edata, CD_MEDGE, edges, totedge, nullptr);
|
||||
me->totedge = totedge;
|
||||
|
||||
BKE_mesh_tag_topology_changed(me);
|
||||
|
@ -1149,11 +1149,11 @@ static int mesh_tessface_calc(Mesh &mesh,
|
|||
sizeof(*mface_to_poly_map) * size_t(totface));
|
||||
}
|
||||
|
||||
CustomData_add_layer_with_data(fdata, CD_MFACE, mface, totface);
|
||||
CustomData_add_layer_with_data(fdata, CD_MFACE, mface, totface, nullptr);
|
||||
|
||||
/* #CD_ORIGINDEX will contain an array of indices from tessellation-faces to the polygons
|
||||
* they are directly tessellated from. */
|
||||
CustomData_add_layer_with_data(fdata, CD_ORIGINDEX, mface_to_poly_map, totface);
|
||||
CustomData_add_layer_with_data(fdata, CD_ORIGINDEX, mface_to_poly_map, totface, nullptr);
|
||||
add_mface_layers(mesh, fdata, ldata, totface);
|
||||
|
||||
/* NOTE: quad detection issue - fourth vertex-index vs fourth loop-index:
|
||||
|
@ -1297,17 +1297,28 @@ void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
|
|||
return;
|
||||
}
|
||||
void *faceset_data = nullptr;
|
||||
const ImplicitSharingInfo *faceset_sharing_info = nullptr;
|
||||
for (const int i : IndexRange(mesh->pdata.totlayer)) {
|
||||
if (mesh->pdata.layers[i].type == CD_SCULPT_FACE_SETS) {
|
||||
faceset_data = mesh->pdata.layers[i].data;
|
||||
mesh->pdata.layers[i].data = nullptr;
|
||||
CustomDataLayer &layer = mesh->pdata.layers[i];
|
||||
if (layer.type == CD_SCULPT_FACE_SETS) {
|
||||
faceset_data = layer.data;
|
||||
faceset_sharing_info = layer.sharing_info;
|
||||
layer.data = nullptr;
|
||||
layer.sharing_info = nullptr;
|
||||
CustomData_free_layer(&mesh->pdata, CD_SCULPT_FACE_SETS, mesh->totpoly, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (faceset_data != nullptr) {
|
||||
CustomData_add_layer_named_with_data(
|
||||
&mesh->pdata, CD_PROP_INT32, faceset_data, mesh->totpoly, ".sculpt_face_set");
|
||||
CustomData_add_layer_named_with_data(&mesh->pdata,
|
||||
CD_PROP_INT32,
|
||||
faceset_data,
|
||||
mesh->totpoly,
|
||||
".sculpt_face_set",
|
||||
faceset_sharing_info);
|
||||
}
|
||||
if (faceset_sharing_info != nullptr) {
|
||||
faceset_sharing_info->remove_user_and_delete_if_last();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1815,28 +1826,31 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
|
|||
uv_names[i] = new_name;
|
||||
|
||||
CustomData_add_layer_named_with_data(
|
||||
&mesh->ldata, CD_PROP_FLOAT2, coords, mesh->totloop, new_name);
|
||||
&mesh->ldata, CD_PROP_FLOAT2, coords, mesh->totloop, new_name, nullptr);
|
||||
char buffer[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
if (vert_selection) {
|
||||
CustomData_add_layer_named_with_data(&mesh->ldata,
|
||||
CD_PROP_BOOL,
|
||||
vert_selection,
|
||||
mesh->totloop,
|
||||
BKE_uv_map_vert_select_name_get(new_name, buffer));
|
||||
BKE_uv_map_vert_select_name_get(new_name, buffer),
|
||||
nullptr);
|
||||
}
|
||||
if (edge_selection) {
|
||||
CustomData_add_layer_named_with_data(&mesh->ldata,
|
||||
CD_PROP_BOOL,
|
||||
edge_selection,
|
||||
mesh->totloop,
|
||||
BKE_uv_map_edge_select_name_get(new_name, buffer));
|
||||
BKE_uv_map_edge_select_name_get(new_name, buffer),
|
||||
nullptr);
|
||||
}
|
||||
if (pin) {
|
||||
CustomData_add_layer_named_with_data(&mesh->ldata,
|
||||
CD_PROP_BOOL,
|
||||
pin,
|
||||
mesh->totloop,
|
||||
BKE_uv_map_pin_name_get(new_name, buffer));
|
||||
BKE_uv_map_pin_name_get(new_name, buffer),
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2272,7 +2286,8 @@ void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh)
|
|||
});
|
||||
CustomData old_poly_data = mesh->pdata;
|
||||
CustomData_reset(&mesh->pdata);
|
||||
CustomData_copy(&old_poly_data, &mesh->pdata, CD_MASK_MESH.pmask, CD_CONSTRUCT, mesh->totpoly);
|
||||
CustomData_copy_layout(
|
||||
&old_poly_data, &mesh->pdata, CD_MASK_MESH.pmask, CD_CONSTRUCT, mesh->totpoly);
|
||||
|
||||
int offset = 0;
|
||||
for (const int i : orig_indices.index_range()) {
|
||||
|
|
|
@ -224,6 +224,7 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
|
|||
mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
|
||||
if (mesh->runtime->shrinkwrap_data) {
|
||||
BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data);
|
||||
mesh->runtime->shrinkwrap_data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1302,12 +1302,7 @@ float paint_grid_paint_mask(const GridPaintMask *gpm, uint level, uint x, uint y
|
|||
|
||||
void paint_update_brush_rake_rotation(UnifiedPaintSettings *ups, Brush *brush, float rotation)
|
||||
{
|
||||
if (brush->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) {
|
||||
ups->brush_rotation = rotation;
|
||||
}
|
||||
else {
|
||||
ups->brush_rotation = 0.0f;
|
||||
}
|
||||
ups->brush_rotation = rotation;
|
||||
|
||||
if (brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE) {
|
||||
ups->brush_rotation_sec = rotation;
|
||||
|
@ -1322,17 +1317,19 @@ static bool paint_rake_rotation_active(const MTex &mtex)
|
|||
return mtex.tex && mtex.brush_angle_mode & MTEX_ANGLE_RAKE;
|
||||
}
|
||||
|
||||
static bool paint_rake_rotation_active(const Brush &brush)
|
||||
static const bool paint_rake_rotation_active(const Brush &brush, ePaintMode paint_mode)
|
||||
{
|
||||
return paint_rake_rotation_active(brush.mtex) || paint_rake_rotation_active(brush.mask_mtex);
|
||||
return paint_rake_rotation_active(brush.mtex) || paint_rake_rotation_active(brush.mask_mtex) ||
|
||||
BKE_brush_has_cube_tip(&brush, paint_mode);
|
||||
}
|
||||
|
||||
bool paint_calculate_rake_rotation(UnifiedPaintSettings *ups,
|
||||
Brush *brush,
|
||||
const float mouse_pos[2])
|
||||
const float mouse_pos[2],
|
||||
ePaintMode paint_mode)
|
||||
{
|
||||
bool ok = false;
|
||||
if (paint_rake_rotation_active(*brush)) {
|
||||
if (paint_rake_rotation_active(*brush, paint_mode)) {
|
||||
const float r = RAKE_THRESHHOLD;
|
||||
float rotation;
|
||||
|
||||
|
|
|
@ -64,25 +64,24 @@ static void pointcloud_init_data(ID *id)
|
|||
CustomData_reset(&pointcloud->pdata);
|
||||
CustomData_add_layer_named(&pointcloud->pdata,
|
||||
CD_PROP_FLOAT3,
|
||||
CD_SET_DEFAULT,
|
||||
CD_CONSTRUCT,
|
||||
pointcloud->totpoint,
|
||||
POINTCLOUD_ATTR_POSITION);
|
||||
|
||||
pointcloud->runtime = new blender::bke::PointCloudRuntime();
|
||||
}
|
||||
|
||||
static void pointcloud_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag)
|
||||
static void pointcloud_copy_data(Main * /*bmain*/,
|
||||
ID *id_dst,
|
||||
const ID *id_src,
|
||||
const int /*flag*/)
|
||||
{
|
||||
PointCloud *pointcloud_dst = (PointCloud *)id_dst;
|
||||
const PointCloud *pointcloud_src = (const PointCloud *)id_src;
|
||||
pointcloud_dst->mat = static_cast<Material **>(MEM_dupallocN(pointcloud_src->mat));
|
||||
|
||||
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
|
||||
CustomData_copy(&pointcloud_src->pdata,
|
||||
&pointcloud_dst->pdata,
|
||||
CD_MASK_ALL,
|
||||
alloc_type,
|
||||
pointcloud_dst->totpoint);
|
||||
CustomData_copy(
|
||||
&pointcloud_src->pdata, &pointcloud_dst->pdata, CD_MASK_ALL, pointcloud_dst->totpoint);
|
||||
|
||||
pointcloud_dst->runtime = new blender::bke::PointCloudRuntime();
|
||||
pointcloud_dst->runtime->bounds_cache = pointcloud_src->runtime->bounds_cache;
|
||||
|
@ -203,21 +202,18 @@ static void pointcloud_random(PointCloud *pointcloud)
|
|||
RNG *rng = BLI_rng_new(0);
|
||||
|
||||
blender::bke::MutableAttributeAccessor attributes = pointcloud->attributes_for_write();
|
||||
blender::bke::SpanAttributeWriter positions =
|
||||
attributes.lookup_or_add_for_write_only_span<float3>(POINTCLOUD_ATTR_POSITION,
|
||||
ATTR_DOMAIN_POINT);
|
||||
blender::MutableSpan<float3> positions = pointcloud->positions_for_write();
|
||||
blender::bke::SpanAttributeWriter<float> radii =
|
||||
attributes.lookup_or_add_for_write_only_span<float>(POINTCLOUD_ATTR_RADIUS,
|
||||
ATTR_DOMAIN_POINT);
|
||||
|
||||
for (const int i : positions.span.index_range()) {
|
||||
positions.span[i] =
|
||||
float3(BLI_rng_get_float(rng), BLI_rng_get_float(rng), BLI_rng_get_float(rng)) * 2.0f -
|
||||
1.0f;
|
||||
for (const int i : positions.index_range()) {
|
||||
positions[i] = float3(BLI_rng_get_float(rng), BLI_rng_get_float(rng), BLI_rng_get_float(rng)) *
|
||||
2.0f -
|
||||
1.0f;
|
||||
radii.span[i] = 0.05f * BLI_rng_get_float(rng);
|
||||
}
|
||||
|
||||
positions.finish();
|
||||
radii.finish();
|
||||
|
||||
BLI_rng_free(rng);
|
||||
|
@ -259,27 +255,12 @@ void BKE_pointcloud_nomain_to_pointcloud(PointCloud *pointcloud_src,
|
|||
{
|
||||
BLI_assert(pointcloud_src->id.tag & LIB_TAG_NO_MAIN);
|
||||
|
||||
eCDAllocType alloctype = CD_DUPLICATE;
|
||||
|
||||
if (take_ownership) {
|
||||
bool has_any_referenced_layers = CustomData_has_referenced(&pointcloud_src->pdata);
|
||||
|
||||
if (!has_any_referenced_layers) {
|
||||
alloctype = CD_ASSIGN;
|
||||
}
|
||||
}
|
||||
|
||||
CustomData_free(&pointcloud_dst->pdata, pointcloud_dst->totpoint);
|
||||
|
||||
const int totpoint = pointcloud_dst->totpoint = pointcloud_src->totpoint;
|
||||
CustomData_copy(
|
||||
&pointcloud_src->pdata, &pointcloud_dst->pdata, CD_MASK_ALL, alloctype, totpoint);
|
||||
CustomData_copy(&pointcloud_src->pdata, &pointcloud_dst->pdata, CD_MASK_ALL, totpoint);
|
||||
|
||||
if (take_ownership) {
|
||||
if (alloctype == CD_ASSIGN) {
|
||||
/* Free the CustomData but keep the layers. */
|
||||
CustomData_free_typemask(&pointcloud_src->pdata, pointcloud_src->totpoint, 0);
|
||||
}
|
||||
BKE_id_free(nullptr, pointcloud_src);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -221,11 +221,11 @@ static void vertex_interpolation_init(const SubdivMeshContext *ctx,
|
|||
else {
|
||||
vertex_interpolation->vertex_data = &vertex_interpolation->vertex_data_storage;
|
||||
/* Allocate storage for loops corresponding to ptex corners. */
|
||||
CustomData_copy(&ctx->coarse_mesh->vdata,
|
||||
&vertex_interpolation->vertex_data_storage,
|
||||
CD_MASK_EVERYTHING.vmask,
|
||||
CD_SET_DEFAULT,
|
||||
4);
|
||||
CustomData_copy_layout(&ctx->coarse_mesh->vdata,
|
||||
&vertex_interpolation->vertex_data_storage,
|
||||
CD_MASK_EVERYTHING.vmask,
|
||||
CD_SET_DEFAULT,
|
||||
4);
|
||||
/* Initialize indices. */
|
||||
vertex_interpolation->vertex_indices[0] = 0;
|
||||
vertex_interpolation->vertex_indices[1] = 1;
|
||||
|
@ -351,11 +351,11 @@ static void loop_interpolation_init(const SubdivMeshContext *ctx,
|
|||
else {
|
||||
loop_interpolation->loop_data = &loop_interpolation->loop_data_storage;
|
||||
/* Allocate storage for loops corresponding to ptex corners. */
|
||||
CustomData_copy(&ctx->coarse_mesh->ldata,
|
||||
&loop_interpolation->loop_data_storage,
|
||||
CD_MASK_EVERYTHING.lmask,
|
||||
CD_SET_DEFAULT,
|
||||
4);
|
||||
CustomData_copy_layout(&ctx->coarse_mesh->ldata,
|
||||
&loop_interpolation->loop_data_storage,
|
||||
CD_MASK_EVERYTHING.lmask,
|
||||
CD_SET_DEFAULT,
|
||||
4);
|
||||
/* Initialize indices. */
|
||||
loop_interpolation->loop_indices[0] = 0;
|
||||
loop_interpolation->loop_indices[1] = 1;
|
||||
|
|
|
@ -73,7 +73,7 @@ inline void gather(const VArray<T> &src,
|
|||
{
|
||||
BLI_assert(indices.size() == dst.size());
|
||||
threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
|
||||
src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range).data());
|
||||
src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bli
|
||||
*
|
||||
* This file only exists to forward declare `blender::ImplicitSharingInfo` in C code.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace blender {
|
||||
class ImplicitSharingInfo;
|
||||
}
|
||||
using ImplicitSharingInfoHandle = blender::ImplicitSharingInfo;
|
||||
|
||||
#else
|
||||
|
||||
typedef struct ImplicitSharingInfoHandle ImplicitSharingInfoHandle;
|
||||
|
||||
#endif
|
|
@ -243,6 +243,7 @@ set(SRC
|
|||
BLI_hash_tables.hh
|
||||
BLI_heap.h
|
||||
BLI_heap_simple.h
|
||||
BLI_implicit_sharing.h
|
||||
BLI_implicit_sharing.hh
|
||||
BLI_implicit_sharing_ptr.hh
|
||||
BLI_index_mask.hh
|
||||
|
|
|
@ -346,13 +346,15 @@ void extract_normalized_words(StringRef str,
|
|||
Vector<StringRef, 64> &r_words)
|
||||
{
|
||||
const uint32_t unicode_space = uint32_t(' ');
|
||||
const uint32_t unicode_slash = uint32_t('/');
|
||||
const uint32_t unicode_right_triangle = UI_MENU_ARROW_SEP_UNICODE;
|
||||
|
||||
BLI_assert(unicode_space == BLI_str_utf8_as_unicode(" "));
|
||||
BLI_assert(unicode_slash == BLI_str_utf8_as_unicode("/"));
|
||||
BLI_assert(unicode_right_triangle == BLI_str_utf8_as_unicode(UI_MENU_ARROW_SEP));
|
||||
|
||||
auto is_separator = [&](uint32_t unicode) {
|
||||
return ELEM(unicode, unicode_space, unicode_right_triangle);
|
||||
return ELEM(unicode, unicode_space, unicode_slash, unicode_right_triangle);
|
||||
};
|
||||
|
||||
/* Make a copy of the string so that we can edit it. */
|
||||
|
|
|
@ -2237,32 +2237,6 @@ static void *restore_pointer_by_name(IDNameLib_Map *id_map, ID *id, ePointerUser
|
|||
#endif
|
||||
}
|
||||
|
||||
static void lib_link_seq_clipboard_pt_restore(ID *id, IDNameLib_Map *id_map)
|
||||
{
|
||||
if (id) {
|
||||
/* clipboard must ensure this */
|
||||
BLI_assert(id->newid != nullptr);
|
||||
id->newid = static_cast<ID *>(restore_pointer_by_name(id_map, id->newid, USER_REAL));
|
||||
}
|
||||
}
|
||||
static bool lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
|
||||
{
|
||||
IDNameLib_Map *id_map = static_cast<IDNameLib_Map *>(arg_pt);
|
||||
|
||||
lib_link_seq_clipboard_pt_restore(reinterpret_cast<ID *>(seq->scene), id_map);
|
||||
lib_link_seq_clipboard_pt_restore(reinterpret_cast<ID *>(seq->scene_camera), id_map);
|
||||
lib_link_seq_clipboard_pt_restore(reinterpret_cast<ID *>(seq->clip), id_map);
|
||||
lib_link_seq_clipboard_pt_restore(reinterpret_cast<ID *>(seq->mask), id_map);
|
||||
lib_link_seq_clipboard_pt_restore(reinterpret_cast<ID *>(seq->sound), id_map);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void lib_link_clipboard_restore(IDNameLib_Map *id_map)
|
||||
{
|
||||
/* update IDs stored in sequencer clipboard */
|
||||
SEQ_for_each_callback(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map);
|
||||
}
|
||||
|
||||
static int lib_link_main_data_restore_cb(LibraryIDLinkCallbackData *cb_data)
|
||||
{
|
||||
const int cb_flag = cb_data->cb_flag;
|
||||
|
@ -2674,9 +2648,6 @@ void blo_lib_link_restore(Main *oldmain,
|
|||
* that is just some minor harmless double-processing. */
|
||||
lib_link_main_data_restore(id_map, newmain);
|
||||
|
||||
/* update IDs stored in all possible clipboards */
|
||||
lib_link_clipboard_restore(id_map);
|
||||
|
||||
BKE_main_idmap_destroy(id_map);
|
||||
}
|
||||
|
||||
|
|
|
@ -273,19 +273,19 @@ static void customdata_version_242(Mesh *me)
|
|||
int a, mtfacen, mcoln;
|
||||
|
||||
if (!me->vdata.totlayer) {
|
||||
CustomData_add_layer_with_data(&me->vdata, CD_MVERT, me->mvert, me->totvert);
|
||||
CustomData_add_layer_with_data(&me->vdata, CD_MVERT, me->mvert, me->totvert, NULL);
|
||||
|
||||
if (me->dvert) {
|
||||
CustomData_add_layer_with_data(&me->vdata, CD_MDEFORMVERT, me->dvert, me->totvert);
|
||||
CustomData_add_layer_with_data(&me->vdata, CD_MDEFORMVERT, me->dvert, me->totvert, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!me->edata.totlayer) {
|
||||
CustomData_add_layer_with_data(&me->edata, CD_MEDGE, me->medge, me->totedge);
|
||||
CustomData_add_layer_with_data(&me->edata, CD_MEDGE, me->medge, me->totedge, NULL);
|
||||
}
|
||||
|
||||
if (!me->fdata.totlayer) {
|
||||
CustomData_add_layer_with_data(&me->fdata, CD_MFACE, me->mface, me->totface);
|
||||
CustomData_add_layer_with_data(&me->fdata, CD_MFACE, me->mface, me->totface, NULL);
|
||||
|
||||
if (me->tface) {
|
||||
if (me->mcol) {
|
||||
|
@ -308,7 +308,7 @@ static void customdata_version_242(Mesh *me)
|
|||
me->tface = NULL;
|
||||
}
|
||||
else if (me->mcol) {
|
||||
CustomData_add_layer_with_data(&me->fdata, CD_MCOL, me->mcol, me->totface);
|
||||
CustomData_add_layer_with_data(&me->fdata, CD_MCOL, me->mcol, me->totface, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -517,16 +517,16 @@ void BM_mesh_copy_init_customdata_from_mesh_array(BMesh *bm_dst,
|
|||
&me_src->ldata, CD_MASK_BMESH.pmask);
|
||||
|
||||
if (i == 0) {
|
||||
CustomData_copy(&mesh_vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy(&mesh_edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy(&mesh_pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy(&mesh_ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&mesh_vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&mesh_edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&mesh_pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&mesh_ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
|
||||
}
|
||||
else {
|
||||
CustomData_merge(&mesh_vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_merge(&mesh_edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
|
||||
CustomData_merge(&mesh_pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_merge(&mesh_ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_merge_layout(&mesh_vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_merge_layout(&mesh_edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
|
||||
CustomData_merge_layout(&mesh_pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_merge_layout(&mesh_ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(mesh_vdata.layers);
|
||||
|
@ -554,10 +554,10 @@ void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const BMAllocTem
|
|||
allocsize = &bm_mesh_allocsize_default;
|
||||
}
|
||||
|
||||
CustomData_copy(&bm_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy(&bm_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy(&bm_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy(&bm_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&bm_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&bm_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&bm_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&bm_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
|
||||
|
||||
CustomData_bmesh_init_pool(&bm_dst->vdata, allocsize->totvert, BM_VERT);
|
||||
CustomData_bmesh_init_pool(&bm_dst->edata, allocsize->totedge, BM_EDGE);
|
||||
|
|
|
@ -268,10 +268,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
|
|||
if (me->totvert == 0) {
|
||||
if (is_new) {
|
||||
/* No verts? still copy custom-data layout. */
|
||||
CustomData_copy(&mesh_vdata, &bm->vdata, mask.vmask, CD_CONSTRUCT, 0);
|
||||
CustomData_copy(&mesh_edata, &bm->edata, mask.emask, CD_CONSTRUCT, 0);
|
||||
CustomData_copy(&mesh_pdata, &bm->pdata, mask.pmask, CD_CONSTRUCT, 0);
|
||||
CustomData_copy(&mesh_ldata, &bm->ldata, mask.lmask, CD_CONSTRUCT, 0);
|
||||
CustomData_copy_layout(&mesh_vdata, &bm->vdata, mask.vmask, CD_CONSTRUCT, 0);
|
||||
CustomData_copy_layout(&mesh_edata, &bm->edata, mask.emask, CD_CONSTRUCT, 0);
|
||||
CustomData_copy_layout(&mesh_pdata, &bm->pdata, mask.pmask, CD_CONSTRUCT, 0);
|
||||
CustomData_copy_layout(&mesh_ldata, &bm->ldata, mask.lmask, CD_CONSTRUCT, 0);
|
||||
|
||||
CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
|
||||
CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
|
||||
|
@ -287,16 +287,20 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
|
|||
}
|
||||
|
||||
if (is_new) {
|
||||
CustomData_copy(&mesh_vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy(&mesh_edata, &bm->edata, mask.emask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy(&mesh_pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy(&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&mesh_vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&mesh_edata, &bm->edata, mask.emask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&mesh_pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, 0);
|
||||
CustomData_copy_layout(&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, 0);
|
||||
}
|
||||
else {
|
||||
CustomData_bmesh_merge(&mesh_vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, bm, BM_VERT);
|
||||
CustomData_bmesh_merge(&mesh_edata, &bm->edata, mask.emask, CD_SET_DEFAULT, bm, BM_EDGE);
|
||||
CustomData_bmesh_merge(&mesh_pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, bm, BM_FACE);
|
||||
CustomData_bmesh_merge(&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, bm, BM_LOOP);
|
||||
CustomData_bmesh_merge_layout(
|
||||
&mesh_vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, bm, BM_VERT);
|
||||
CustomData_bmesh_merge_layout(
|
||||
&mesh_edata, &bm->edata, mask.emask, CD_SET_DEFAULT, bm, BM_EDGE);
|
||||
CustomData_bmesh_merge_layout(
|
||||
&mesh_pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, bm, BM_FACE);
|
||||
CustomData_bmesh_merge_layout(
|
||||
&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, bm, BM_LOOP);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -1382,13 +1386,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
|
|||
using namespace blender;
|
||||
const int old_verts_num = me->totvert;
|
||||
|
||||
CustomData_free(&me->vdata, me->totvert);
|
||||
CustomData_free(&me->edata, me->totedge);
|
||||
CustomData_free(&me->fdata, me->totface);
|
||||
CustomData_free(&me->ldata, me->totloop);
|
||||
CustomData_free(&me->pdata, me->totpoly);
|
||||
MEM_SAFE_FREE(me->poly_offset_indices);
|
||||
BKE_mesh_runtime_clear_geometry(me);
|
||||
BKE_mesh_clear_geometry(me);
|
||||
|
||||
me->totvert = bm->totvert;
|
||||
me->totedge = bm->totedge;
|
||||
|
@ -1400,10 +1398,10 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
|
|||
{
|
||||
CustomData_MeshMasks mask = CD_MASK_MESH;
|
||||
CustomData_MeshMasks_update(&mask, ¶ms->cd_mask_extra);
|
||||
CustomData_copy(&bm->vdata, &me->vdata, mask.vmask, CD_SET_DEFAULT, me->totvert);
|
||||
CustomData_copy(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge);
|
||||
CustomData_copy(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop);
|
||||
CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly);
|
||||
CustomData_copy_layout(&bm->vdata, &me->vdata, mask.vmask, CD_SET_DEFAULT, me->totvert);
|
||||
CustomData_copy_layout(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge);
|
||||
CustomData_copy_layout(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop);
|
||||
CustomData_copy_layout(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly);
|
||||
}
|
||||
|
||||
bool need_select_vert = false;
|
||||
|
@ -1615,10 +1613,10 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
|
|||
CustomData_MeshMasks_update(&mask, cd_mask_extra);
|
||||
}
|
||||
mask.vmask &= ~CD_MASK_SHAPEKEY;
|
||||
CustomData_merge(&bm->vdata, &me->vdata, mask.vmask, CD_CONSTRUCT, me->totvert);
|
||||
CustomData_merge(&bm->edata, &me->edata, mask.emask, CD_CONSTRUCT, me->totedge);
|
||||
CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_CONSTRUCT, me->totloop);
|
||||
CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_CONSTRUCT, me->totpoly);
|
||||
CustomData_merge_layout(&bm->vdata, &me->vdata, mask.vmask, CD_CONSTRUCT, me->totvert);
|
||||
CustomData_merge_layout(&bm->edata, &me->edata, mask.emask, CD_CONSTRUCT, me->totedge);
|
||||
CustomData_merge_layout(&bm->ldata, &me->ldata, mask.lmask, CD_CONSTRUCT, me->totloop);
|
||||
CustomData_merge_layout(&bm->pdata, &me->pdata, mask.pmask, CD_CONSTRUCT, me->totpoly);
|
||||
|
||||
me->runtime->deformed_only = true;
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@ void main()
|
|||
view_clipping_distances(world_pos);
|
||||
|
||||
bool show_handle = showCurveHandles;
|
||||
if ((uint(curveHandleDisplay) == CURVE_HANDLE_SELECTED) && ((data & VERT_SELECTED_BEZT_HANDLE) == 0u)) {
|
||||
if ((uint(curveHandleDisplay) == CURVE_HANDLE_SELECTED) &&
|
||||
((data & VERT_SELECTED_BEZT_HANDLE) == 0u)) {
|
||||
show_handle = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -766,12 +766,17 @@ class Texture : NonCopyable {
|
|||
return GPU_texture_height(tx_);
|
||||
}
|
||||
|
||||
int depth() const
|
||||
{
|
||||
return GPU_texture_depth(tx_);
|
||||
}
|
||||
|
||||
int pixel_count() const
|
||||
{
|
||||
return GPU_texture_width(tx_) * GPU_texture_height(tx_);
|
||||
}
|
||||
|
||||
bool depth() const
|
||||
bool is_depth() const
|
||||
{
|
||||
return GPU_texture_has_depth_format(tx_);
|
||||
}
|
||||
|
|
|
@ -250,7 +250,7 @@ static void pointcloud_extract_position_and_radius(const PointCloud &pointcloud,
|
|||
using namespace blender;
|
||||
|
||||
const bke::AttributeAccessor attributes = pointcloud.attributes();
|
||||
const VArraySpan<float3> positions = attributes.lookup<float3>("position", ATTR_DOMAIN_POINT);
|
||||
const Span<float3> positions = pointcloud.positions();
|
||||
const VArray<float> radii = attributes.lookup<float>("radius", ATTR_DOMAIN_POINT);
|
||||
static GPUVertFormat format = {0};
|
||||
if (format.attr_len == 0) {
|
||||
|
|
|
@ -741,7 +741,7 @@ void ANIM_frame_channel_y_extents(bContext *C, bAnimContext *ac)
|
|||
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS |
|
||||
ANIMFILTER_FCURVESONLY);
|
||||
ANIMFILTER_FCURVESONLY | ANIMFILTER_CURVE_VISIBLE);
|
||||
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
||||
|
||||
rctf bounds = {.xmin = FLT_MAX, .xmax = -FLT_MAX, .ymin = FLT_MAX, .ymax = -FLT_MAX};
|
||||
|
|
|
@ -381,7 +381,7 @@ static int insert_into_textbuf(Object *obedit, uintptr_t c)
|
|||
}
|
||||
ef->textbuf[ef->pos] = c;
|
||||
ef->textbufinfo[ef->pos] = cu->curinfo;
|
||||
ef->textbufinfo[ef->pos].kern = 0;
|
||||
ef->textbufinfo[ef->pos].kern = 0.0f;
|
||||
ef->textbufinfo[ef->pos].mat_nr = obedit->actcol;
|
||||
|
||||
ef->pos++;
|
||||
|
@ -1346,7 +1346,7 @@ static int change_spacing_exec(bContext *C, wmOperator *op)
|
|||
Object *obedit = CTX_data_edit_object(C);
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
int kern, delta = RNA_int_get(op->ptr, "delta");
|
||||
float kern, delta = RNA_float_get(op->ptr, "delta");
|
||||
int selstart, selend;
|
||||
bool changed = false;
|
||||
|
||||
|
@ -1361,7 +1361,6 @@ static int change_spacing_exec(bContext *C, wmOperator *op)
|
|||
|
||||
for (int i = selstart; i <= selend; i++) {
|
||||
kern = ef->textbufinfo[i].kern + delta;
|
||||
CLAMP(kern, -20, 20);
|
||||
|
||||
if (ef->textbufinfo[i].kern != kern) {
|
||||
ef->textbufinfo[i].kern = kern;
|
||||
|
@ -1392,15 +1391,15 @@ void FONT_OT_change_spacing(wmOperatorType *ot)
|
|||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
RNA_def_int(ot->srna,
|
||||
"delta",
|
||||
1,
|
||||
-20,
|
||||
20,
|
||||
"Delta",
|
||||
"Amount to decrease or increase character spacing with",
|
||||
-20,
|
||||
20);
|
||||
RNA_def_float(ot->srna,
|
||||
"delta",
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
"Delta",
|
||||
"Amount to decrease or increase character spacing with",
|
||||
0.0,
|
||||
0.0);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -57,3 +57,8 @@ void ED_curves_transverts_create(Curves *curves_id, TransVertStore *tvs)
|
|||
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
ed::curves::transverts_from_curves_positions_create(curves, tvs);
|
||||
}
|
||||
|
||||
int *ED_curves_offsets_for_write(Curves *curves_id)
|
||||
{
|
||||
return curves_id->geometry.wrap().offsets_for_write().data();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define DIAL_RESOLUTION 48
|
||||
|
||||
/**
|
||||
* Data for common interactions. Used in gizmo_library_utils.c functions.
|
||||
*/
|
||||
|
@ -73,6 +75,13 @@ bool gizmo_window_project_2d(bContext *C,
|
|||
bool gizmo_window_project_3d(
|
||||
bContext *C, const struct wmGizmo *gz, const float mval[2], bool use_offset, float r_co[3]);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Gizmo RNA Utils. */
|
||||
|
||||
struct wmGizmo *gizmo_find_from_properties(const struct IDProperty *properties,
|
||||
const int spacetype,
|
||||
const int regionid);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Gizmo drawing */
|
||||
|
||||
|
|
|
@ -15,12 +15,15 @@
|
|||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
@ -245,3 +248,38 @@ bool gizmo_window_project_3d(
|
|||
copy_v2_v2(r_co, co);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name RNA Utils
|
||||
* \{ */
|
||||
|
||||
/* Based on 'rna_GizmoProperties_find_operator'. */
|
||||
wmGizmo *gizmo_find_from_properties(const struct IDProperty *properties,
|
||||
const int spacetype,
|
||||
const int regionid)
|
||||
{
|
||||
for (bScreen *screen = G_MAIN->screens.first; screen; screen = screen->id.next) {
|
||||
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||
if (!ELEM(spacetype, SPACE_TYPE_ANY, area->spacetype)) {
|
||||
continue;
|
||||
}
|
||||
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
|
||||
if (region->gizmo_map == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (!ELEM(regionid, RGN_TYPE_ANY, region->regiontype)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(region->gizmo_map)) {
|
||||
LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
|
||||
if (gz->properties == properties) {
|
||||
return gz;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#include "../gizmo_library_intern.h"
|
||||
|
||||
/* to use custom arrows exported to geom_arrow_gizmo.c */
|
||||
//#define USE_GIZMO_CUSTOM_ARROWS
|
||||
// #define USE_GIZMO_CUSTOM_ARROWS
|
||||
|
||||
/* Margin to add when selecting the arrow. */
|
||||
#define ARROW_SELECT_THRESHOLD_PX (5)
|
||||
|
@ -115,6 +115,29 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow,
|
|||
immUniform1f("lineWidth", arrow->gizmo.line_width * U.pixelsize);
|
||||
wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GPU_PRIM_LINE_LOOP);
|
||||
}
|
||||
else if (draw_style == ED_GIZMO_ARROW_STYLE_PLANE) {
|
||||
const float scale = 0.1f;
|
||||
const float verts[4][3] = {
|
||||
{0, 0, 0},
|
||||
{scale, 0, scale},
|
||||
{0, 0, 2 * scale},
|
||||
{-scale, 0, scale},
|
||||
};
|
||||
|
||||
const float color_inner[4] = {UNPACK3(color), color[3] * 0.5f};
|
||||
|
||||
/* Translate to line end. */
|
||||
GPU_matrix_push();
|
||||
GPU_matrix_translate_3f(0.0f, 0.0f, arrow_length);
|
||||
|
||||
immUniform1f("lineWidth", arrow->gizmo.line_width * U.pixelsize);
|
||||
wm_gizmo_vec_draw(color, verts, ARRAY_SIZE(verts), pos, GPU_PRIM_LINE_LOOP);
|
||||
|
||||
immUnbindProgram();
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
wm_gizmo_vec_draw(color_inner, verts, ARRAY_SIZE(verts), pos, GPU_PRIM_TRI_FAN);
|
||||
GPU_matrix_pop();
|
||||
}
|
||||
else {
|
||||
#ifdef USE_GIZMO_CUSTOM_ARROWS
|
||||
wm_gizmo_geometryinfo_draw(&wm_gizmo_geom_data_arrow, select, color);
|
||||
|
@ -177,6 +200,19 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow,
|
|||
if (unbind_shader) {
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
if (draw_options & ED_GIZMO_ARROW_DRAW_FLAG_ORIGIN) {
|
||||
const float point_size = 10 * U.pixelsize;
|
||||
GPU_program_point_size(true);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
|
||||
immUniform1f("size", point_size);
|
||||
immUniformColor4fv(color);
|
||||
immBegin(GPU_PRIM_POINTS, 1);
|
||||
immVertex3f(pos, 0.0f, 0.0f, 0.0f);
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
GPU_program_point_size(false);
|
||||
}
|
||||
}
|
||||
|
||||
static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool highlight)
|
||||
|
@ -504,10 +540,12 @@ static void GIZMO_GT_arrow_3d(wmGizmoType *gzt)
|
|||
{ED_GIZMO_ARROW_STYLE_CROSS, "CROSS", 0, "Cross", ""},
|
||||
{ED_GIZMO_ARROW_STYLE_BOX, "BOX", 0, "Box", ""},
|
||||
{ED_GIZMO_ARROW_STYLE_CONE, "CONE", 0, "Cone", ""},
|
||||
{ED_GIZMO_ARROW_STYLE_PLANE, "PLANE", 0, "Plane", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
static EnumPropertyItem rna_enum_draw_options_items[] = {
|
||||
{ED_GIZMO_ARROW_DRAW_FLAG_STEM, "STEM", 0, "Stem", ""},
|
||||
{ED_GIZMO_ARROW_DRAW_FLAG_ORIGIN, "ORIGIN", 0, "Origin", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
static EnumPropertyItem rna_enum_transform_items[] = {
|
||||
|
|
|
@ -71,7 +71,6 @@ typedef struct DialInteraction {
|
|||
} DialInteraction;
|
||||
|
||||
#define DIAL_WIDTH 1.0f
|
||||
#define DIAL_RESOLUTION 48
|
||||
|
||||
/* Could make option, negative to clip more (don't show when view aligned). */
|
||||
#define DIAL_CLIP_BIAS 0.02
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "../gizmo_library_intern.h"
|
||||
|
||||
#define MVAL_MAX_PX_DIST 12.0f
|
||||
#define RING_2D_RESOLUTION 32
|
||||
|
||||
typedef struct MoveGizmo3D {
|
||||
wmGizmo gizmo;
|
||||
|
@ -116,10 +117,10 @@ static void move_geom_draw(const wmGizmo *gz,
|
|||
|
||||
if (draw_style == ED_GIZMO_MOVE_STYLE_RING_2D) {
|
||||
if (filled) {
|
||||
imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, radius, DIAL_RESOLUTION);
|
||||
imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, radius, RING_2D_RESOLUTION);
|
||||
}
|
||||
else {
|
||||
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, radius, DIAL_RESOLUTION);
|
||||
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, radius, RING_2D_RESOLUTION);
|
||||
}
|
||||
}
|
||||
else if (draw_style == ED_GIZMO_MOVE_STYLE_CROSS_2D) {
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
@ -42,36 +44,135 @@ static float verts_plane[4][3] = {
|
|||
{-1, 1, 0},
|
||||
};
|
||||
|
||||
typedef struct PrimitiveGizmo3D {
|
||||
wmGizmo gizmo;
|
||||
|
||||
int draw_style;
|
||||
float arc_inner_factor;
|
||||
bool draw_inner;
|
||||
} PrimitiveGizmo3D;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name RNA callbacks */
|
||||
|
||||
static void gizmo_primitive_draw_geom(const float col_inner[4],
|
||||
const float col_outer[4],
|
||||
const int draw_style)
|
||||
static PrimitiveGizmo3D *gizmo_primitive_rna_find_operator(PointerRNA *ptr)
|
||||
{
|
||||
float(*verts)[3];
|
||||
uint vert_count = 0;
|
||||
|
||||
if (draw_style == ED_GIZMO_PRIMITIVE_STYLE_PLANE) {
|
||||
verts = verts_plane;
|
||||
vert_count = ARRAY_SIZE(verts_plane);
|
||||
}
|
||||
|
||||
if (vert_count > 0) {
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
wm_gizmo_vec_draw(col_inner, verts, vert_count, pos, GPU_PRIM_TRI_FAN);
|
||||
wm_gizmo_vec_draw(col_outer, verts, vert_count, pos, GPU_PRIM_LINE_LOOP);
|
||||
immUnbindProgram();
|
||||
}
|
||||
return (PrimitiveGizmo3D *)gizmo_find_from_properties(ptr->data, SPACE_TYPE_ANY, RGN_TYPE_ANY);
|
||||
}
|
||||
|
||||
static void gizmo_primitive_draw_intern(wmGizmo *gz,
|
||||
const bool UNUSED(select),
|
||||
const bool highlight)
|
||||
static int gizmo_primitive_rna__draw_style_get_fn(struct PointerRNA *ptr,
|
||||
struct PropertyRNA *UNUSED(prop))
|
||||
{
|
||||
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
|
||||
return gz_prim->draw_style;
|
||||
}
|
||||
|
||||
static void gizmo_primitive_rna__draw_style_set_fn(struct PointerRNA *ptr,
|
||||
struct PropertyRNA *UNUSED(prop),
|
||||
int value)
|
||||
{
|
||||
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
|
||||
gz_prim->draw_style = value;
|
||||
}
|
||||
|
||||
static float gizmo_primitive_rna__arc_inner_factor_get_fn(struct PointerRNA *ptr,
|
||||
struct PropertyRNA *UNUSED(prop))
|
||||
{
|
||||
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
|
||||
return gz_prim->arc_inner_factor;
|
||||
}
|
||||
|
||||
static void gizmo_primitive_rna__arc_inner_factor_set_fn(struct PointerRNA *ptr,
|
||||
struct PropertyRNA *UNUSED(prop),
|
||||
float value)
|
||||
{
|
||||
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
|
||||
gz_prim->arc_inner_factor = value;
|
||||
}
|
||||
|
||||
static bool gizmo_primitive_rna__draw_inner_get_fn(struct PointerRNA *ptr,
|
||||
struct PropertyRNA *UNUSED(prop))
|
||||
{
|
||||
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
|
||||
return gz_prim->draw_inner;
|
||||
}
|
||||
|
||||
static void gizmo_primitive_rna__draw_inner_set_fn(struct PointerRNA *ptr,
|
||||
struct PropertyRNA *UNUSED(prop),
|
||||
bool value)
|
||||
{
|
||||
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
|
||||
gz_prim->draw_inner = value;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static void gizmo_primitive_draw_geom(PrimitiveGizmo3D *gz_prim,
|
||||
const float col_inner[4],
|
||||
const float col_outer[4],
|
||||
const int nsegments,
|
||||
const bool draw_inner)
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
const bool use_polyline_shader = gz_prim->gizmo.line_width > 1.0f;
|
||||
|
||||
if (draw_inner || !use_polyline_shader) {
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
}
|
||||
|
||||
if (draw_inner) {
|
||||
if (gz_prim->draw_style == ED_GIZMO_PRIMITIVE_STYLE_PLANE) {
|
||||
wm_gizmo_vec_draw(col_inner, verts_plane, ARRAY_SIZE(verts_plane), pos, GPU_PRIM_TRI_FAN);
|
||||
}
|
||||
else {
|
||||
immUniformColor4fv(col_inner);
|
||||
if (gz_prim->draw_style == ED_GIZMO_PRIMITIVE_STYLE_CIRCLE) {
|
||||
imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, 1.0f, nsegments);
|
||||
}
|
||||
else {
|
||||
BLI_assert(gz_prim->draw_style == ED_GIZMO_PRIMITIVE_STYLE_ANNULUS);
|
||||
imm_draw_disk_partial_fill_3d(
|
||||
pos, 0.0f, 0.0f, 0.0f, gz_prim->arc_inner_factor, 1.0f, nsegments, 0.0f, 360.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw outline. */
|
||||
|
||||
if (use_polyline_shader) {
|
||||
if (draw_inner) {
|
||||
immUnbindProgram();
|
||||
}
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
|
||||
|
||||
float viewport[4];
|
||||
GPU_viewport_size_get_f(viewport);
|
||||
immUniform2fv("viewportSize", &viewport[2]);
|
||||
immUniform1f("lineWidth", gz_prim->gizmo.line_width * U.pixelsize);
|
||||
}
|
||||
|
||||
if (gz_prim->draw_style == ED_GIZMO_PRIMITIVE_STYLE_PLANE) {
|
||||
wm_gizmo_vec_draw(col_outer, verts_plane, ARRAY_SIZE(verts_plane), pos, GPU_PRIM_LINE_LOOP);
|
||||
}
|
||||
else {
|
||||
immUniformColor4fv(col_outer);
|
||||
if (gz_prim->draw_style == ED_GIZMO_PRIMITIVE_STYLE_CIRCLE) {
|
||||
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, nsegments);
|
||||
}
|
||||
else {
|
||||
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, gz_prim->arc_inner_factor, nsegments);
|
||||
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, nsegments);
|
||||
}
|
||||
}
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void gizmo_primitive_draw_intern(wmGizmo *gz, const bool select, const bool highlight)
|
||||
{
|
||||
PrimitiveGizmo3D *gz_prim = (PrimitiveGizmo3D *)gz;
|
||||
|
||||
float color_inner[4], color_outer[4];
|
||||
float matrix_final[4][4];
|
||||
const int draw_style = RNA_enum_get(gz->ptr, "draw_style");
|
||||
|
||||
gizmo_color_get(gz, highlight, color_outer);
|
||||
copy_v4_v4(color_inner, color_outer);
|
||||
|
@ -79,12 +180,15 @@ static void gizmo_primitive_draw_intern(wmGizmo *gz,
|
|||
|
||||
WM_gizmo_calc_matrix_final(gz, matrix_final);
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
GPU_matrix_push();
|
||||
GPU_matrix_mul(matrix_final);
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
gizmo_primitive_draw_geom(color_inner, color_outer, draw_style);
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
gizmo_primitive_draw_geom(gz_prim,
|
||||
color_inner,
|
||||
color_outer,
|
||||
select ? 24 : DIAL_RESOLUTION,
|
||||
gz_prim->draw_inner || select);
|
||||
|
||||
GPU_matrix_pop();
|
||||
|
||||
|
@ -98,12 +202,12 @@ static void gizmo_primitive_draw_intern(wmGizmo *gz,
|
|||
GPU_matrix_push();
|
||||
GPU_matrix_mul(inter->init_matrix_final);
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
gizmo_primitive_draw_geom(color_inner, color_outer, draw_style);
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
gizmo_primitive_draw_geom(
|
||||
gz_prim, color_inner, color_outer, DIAL_RESOLUTION, gz_prim->draw_inner);
|
||||
|
||||
GPU_matrix_pop();
|
||||
}
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
static void gizmo_primitive_draw_select(const bContext *UNUSED(C), wmGizmo *gz, int select_id)
|
||||
|
@ -120,6 +224,12 @@ static void gizmo_primitive_draw(const bContext *UNUSED(C), wmGizmo *gz)
|
|||
static void gizmo_primitive_setup(wmGizmo *gz)
|
||||
{
|
||||
gz->flag |= WM_GIZMO_DRAW_MODAL;
|
||||
|
||||
/* Default Values. */
|
||||
PrimitiveGizmo3D *gz_prim = (PrimitiveGizmo3D *)gz;
|
||||
gz_prim->draw_style = ED_GIZMO_PRIMITIVE_STYLE_PLANE;
|
||||
gz_prim->arc_inner_factor = true;
|
||||
gz_prim->draw_inner = true;
|
||||
}
|
||||
|
||||
static int gizmo_primitive_invoke(bContext *UNUSED(C), wmGizmo *gz, const wmEvent *UNUSED(event))
|
||||
|
@ -148,18 +258,35 @@ static void GIZMO_GT_primitive_3d(wmGizmoType *gzt)
|
|||
gzt->setup = gizmo_primitive_setup;
|
||||
gzt->invoke = gizmo_primitive_invoke;
|
||||
|
||||
gzt->struct_size = sizeof(wmGizmo);
|
||||
gzt->struct_size = sizeof(PrimitiveGizmo3D);
|
||||
|
||||
static EnumPropertyItem rna_enum_draw_style[] = {
|
||||
{ED_GIZMO_PRIMITIVE_STYLE_PLANE, "PLANE", 0, "Plane", ""},
|
||||
{ED_GIZMO_PRIMITIVE_STYLE_CIRCLE, "CIRCLE", 0, "Circle", ""},
|
||||
{ED_GIZMO_PRIMITIVE_STYLE_ANNULUS, "ANNULUS", 0, "Annulus", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
RNA_def_enum(gzt->srna,
|
||||
"draw_style",
|
||||
rna_enum_draw_style,
|
||||
ED_GIZMO_PRIMITIVE_STYLE_PLANE,
|
||||
"Draw Style",
|
||||
"");
|
||||
|
||||
PropertyRNA *prop;
|
||||
prop = RNA_def_enum(gzt->srna,
|
||||
"draw_style",
|
||||
rna_enum_draw_style,
|
||||
ED_GIZMO_PRIMITIVE_STYLE_PLANE,
|
||||
"Draw Style",
|
||||
"");
|
||||
RNA_def_property_enum_funcs_runtime(
|
||||
prop, gizmo_primitive_rna__draw_style_get_fn, gizmo_primitive_rna__draw_style_set_fn, NULL);
|
||||
|
||||
prop = RNA_def_float_factor(
|
||||
gzt->srna, "arc_inner_factor", 0.0f, 0.0f, FLT_MAX, "Arc Inner Factor", "", 0.0f, 1.0f);
|
||||
RNA_def_property_float_funcs_runtime(prop,
|
||||
gizmo_primitive_rna__arc_inner_factor_get_fn,
|
||||
gizmo_primitive_rna__arc_inner_factor_set_fn,
|
||||
NULL);
|
||||
|
||||
prop = RNA_def_boolean(gzt->srna, "draw_inner", true, "Draw Inner", "");
|
||||
RNA_def_property_boolean_funcs_runtime(
|
||||
prop, gizmo_primitive_rna__draw_inner_get_fn, gizmo_primitive_rna__draw_inner_set_fn);
|
||||
}
|
||||
|
||||
void ED_gizmotypes_primitive_3d(void)
|
||||
|
|
|
@ -123,30 +123,9 @@ void ED_gizmotypes_snap_3d_data_get(const struct bContext *C,
|
|||
/** \name RNA callbacks
|
||||
* \{ */
|
||||
|
||||
/* Based on 'rna_GizmoProperties_find_operator'. */
|
||||
static SnapGizmo3D *gizmo_snap_rna_find_operator(PointerRNA *ptr)
|
||||
{
|
||||
IDProperty *properties = ptr->data;
|
||||
for (bScreen *screen = G_MAIN->screens.first; screen; screen = screen->id.next) {
|
||||
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||
if (area->spacetype != SPACE_VIEW3D) {
|
||||
continue;
|
||||
}
|
||||
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
|
||||
if (region->regiontype == RGN_TYPE_WINDOW && region->gizmo_map) {
|
||||
wmGizmoMap *gzmap = region->gizmo_map;
|
||||
LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(gzmap)) {
|
||||
LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
|
||||
if (gz->properties == properties) {
|
||||
return (SnapGizmo3D *)gz;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return (SnapGizmo3D *)gizmo_find_from_properties(ptr->data, SPACE_VIEW3D, RGN_TYPE_WINDOW);
|
||||
}
|
||||
|
||||
static V3DSnapCursorState *gizmo_snap_state_from_rna_get(struct PointerRNA *ptr)
|
||||
|
|
|
@ -38,6 +38,11 @@ float (*ED_curves_point_normals_array_create(const struct Curves *curves_id))[3]
|
|||
*/
|
||||
void ED_curves_transverts_create(struct Curves *curves_id, struct TransVertStore *tvs);
|
||||
|
||||
/**
|
||||
* C wrapper for #CurvesGeometry::offsets_for_write().
|
||||
*/
|
||||
int *ED_curves_offsets_for_write(struct Curves *curves_id);
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -64,6 +64,7 @@ enum {
|
|||
ED_GIZMO_ARROW_STYLE_CROSS = 1,
|
||||
ED_GIZMO_ARROW_STYLE_BOX = 2,
|
||||
ED_GIZMO_ARROW_STYLE_CONE = 3,
|
||||
ED_GIZMO_ARROW_STYLE_PLANE = 4,
|
||||
};
|
||||
|
||||
/* transform */
|
||||
|
@ -78,6 +79,7 @@ enum {
|
|||
enum {
|
||||
/* Show arrow stem. */
|
||||
ED_GIZMO_ARROW_DRAW_FLAG_STEM = (1 << 0),
|
||||
ED_GIZMO_ARROW_DRAW_FLAG_ORIGIN = (1 << 1),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -233,6 +235,8 @@ enum {
|
|||
|
||||
enum {
|
||||
ED_GIZMO_PRIMITIVE_STYLE_PLANE = 0,
|
||||
ED_GIZMO_PRIMITIVE_STYLE_CIRCLE,
|
||||
ED_GIZMO_PRIMITIVE_STYLE_ANNULUS,
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -340,7 +340,6 @@ struct FaceIsland {
|
|||
struct FaceIsland *prev;
|
||||
struct BMFace **faces;
|
||||
int faces_len;
|
||||
rctf bounds_rect;
|
||||
/**
|
||||
* \note While this is duplicate information,
|
||||
* it allows islands from multiple meshes to be stored in the same list.
|
||||
|
|
|
@ -116,18 +116,18 @@ static void ui_popup_block_position(wmWindow *window,
|
|||
const int center_x = (block->direction & UI_DIR_CENTER_X) ? size_x / 2 : 0;
|
||||
const int center_y = (block->direction & UI_DIR_CENTER_Y) ? size_y / 2 : 0;
|
||||
|
||||
const int win_x = WM_window_pixels_x(window);
|
||||
const int win_y = WM_window_pixels_y(window);
|
||||
|
||||
/* Take into account maximum size so we don't have to flip on refresh. */
|
||||
const float max_size_x = max_ff(size_x, handle->max_size_x);
|
||||
const float max_size_y = max_ff(size_y, handle->max_size_y);
|
||||
|
||||
short dir1 = 0, dir2 = 0;
|
||||
|
||||
if (!handle->refresh) {
|
||||
bool left = false, right = false, top = false, down = false;
|
||||
|
||||
const int win_x = WM_window_pixels_x(window);
|
||||
const int win_y = WM_window_pixels_y(window);
|
||||
|
||||
/* Take into account maximum size so we don't have to flip on refresh. */
|
||||
const float max_size_x = max_ff(size_x, handle->max_size_x);
|
||||
const float max_size_y = max_ff(size_y, handle->max_size_y);
|
||||
|
||||
/* check if there's space at all */
|
||||
if (butrct.xmin - max_size_x + center_x > 0.0f) {
|
||||
left = true;
|
||||
|
@ -237,6 +237,15 @@ static void ui_popup_block_position(wmWindow *window,
|
|||
}
|
||||
else if (dir1 == UI_DIR_UP) {
|
||||
offset_y = (butrct.ymax - block->rect.ymin) - offset_overlap;
|
||||
|
||||
if (but->type == UI_BTYPE_COLOR && block->rect.ymax + offset_y > win_y - UI_POPUP_MENU_TOP) {
|
||||
/* Shift this down, aligning the top edge close to the window top. */
|
||||
offset_y = win_y - block->rect.ymax - UI_POPUP_MENU_TOP;
|
||||
/* All four corners should be rounded since this no longer button-aligned. */
|
||||
block->direction = UI_DIR_CENTER_Y;
|
||||
dir1 = UI_DIR_CENTER_Y;
|
||||
}
|
||||
|
||||
if (dir2 == UI_DIR_RIGHT) {
|
||||
offset_x = butrct.xmax - block->rect.xmax + center_x;
|
||||
}
|
||||
|
@ -251,6 +260,15 @@ static void ui_popup_block_position(wmWindow *window,
|
|||
}
|
||||
else if (dir1 == UI_DIR_DOWN) {
|
||||
offset_y = (butrct.ymin - block->rect.ymax) + offset_overlap;
|
||||
|
||||
if (but->type == UI_BTYPE_COLOR && block->rect.ymin + offset_y < UI_SCREEN_MARGIN) {
|
||||
/* Shift this up, aligning the bottom edge close to the window bottom. */
|
||||
offset_y = -block->rect.ymin + UI_SCREEN_MARGIN;
|
||||
/* All four corners should be rounded since this no longer button-aligned. */
|
||||
block->direction = UI_DIR_CENTER_Y;
|
||||
dir1 = UI_DIR_CENTER_Y;
|
||||
}
|
||||
|
||||
if (dir2 == UI_DIR_RIGHT) {
|
||||
offset_x = butrct.xmax - block->rect.xmax + center_x;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BLI_array_utils.h"
|
||||
#include "BLI_implicit_sharing.hh"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_task.hh"
|
||||
|
||||
|
@ -273,8 +274,18 @@ static void um_arraystore_cd_compact(CustomData *cdata,
|
|||
}
|
||||
|
||||
if (layer->data) {
|
||||
if (layer->sharing_info) {
|
||||
/* This assumes that the layer is not shared, which it is not here because it has just
|
||||
* been created in #BM_mesh_bm_to_me. The situation is a bit tricky here, because the
|
||||
* layer data may be freed partially below for e.g. vertex groups. A potentially better
|
||||
* solution might be to not pass "dynamic" layers (see `layer_type_is_dynamic`) to the
|
||||
* array store at all. */
|
||||
BLI_assert(layer->sharing_info->is_mutable());
|
||||
MEM_delete(layer->sharing_info);
|
||||
}
|
||||
MEM_freeN(layer->data);
|
||||
layer->data = nullptr;
|
||||
layer->sharing_info = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -278,7 +278,8 @@ int ED_mesh_uv_add(
|
|||
CD_PROP_FLOAT2,
|
||||
MEM_dupallocN(CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2)),
|
||||
me->totloop,
|
||||
unique_name);
|
||||
unique_name,
|
||||
nullptr);
|
||||
|
||||
is_init = true;
|
||||
}
|
||||
|
@ -1143,7 +1144,7 @@ static void mesh_add_verts(Mesh *mesh, int len)
|
|||
|
||||
int totvert = mesh->totvert + len;
|
||||
CustomData vdata;
|
||||
CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH.vmask, CD_SET_DEFAULT, totvert);
|
||||
CustomData_copy_layout(&mesh->vdata, &vdata, CD_MASK_MESH.vmask, CD_SET_DEFAULT, totvert);
|
||||
CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert);
|
||||
|
||||
if (!CustomData_get_layer_named(&vdata, CD_PROP_FLOAT3, "position")) {
|
||||
|
@ -1177,7 +1178,7 @@ static void mesh_add_edges(Mesh *mesh, int len)
|
|||
totedge = mesh->totedge + len;
|
||||
|
||||
/* Update custom-data. */
|
||||
CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH.emask, CD_SET_DEFAULT, totedge);
|
||||
CustomData_copy_layout(&mesh->edata, &edata, CD_MASK_MESH.emask, CD_SET_DEFAULT, totedge);
|
||||
CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
|
||||
|
||||
if (!CustomData_has_layer(&edata, CD_MEDGE)) {
|
||||
|
@ -1210,7 +1211,7 @@ static void mesh_add_loops(Mesh *mesh, int len)
|
|||
totloop = mesh->totloop + len; /* new face count */
|
||||
|
||||
/* update customdata */
|
||||
CustomData_copy(&mesh->ldata, &ldata, CD_MASK_MESH.lmask, CD_SET_DEFAULT, totloop);
|
||||
CustomData_copy_layout(&mesh->ldata, &ldata, CD_MASK_MESH.lmask, CD_SET_DEFAULT, totloop);
|
||||
CustomData_copy_data(&mesh->ldata, &ldata, 0, 0, mesh->totloop);
|
||||
|
||||
if (!CustomData_get_layer_named(&ldata, CD_PROP_INT32, ".corner_vert")) {
|
||||
|
@ -1247,7 +1248,7 @@ static void mesh_add_polys(Mesh *mesh, int len)
|
|||
totpoly = mesh->totpoly + len; /* new face count */
|
||||
|
||||
/* update customdata */
|
||||
CustomData_copy(&mesh->pdata, &pdata, CD_MASK_MESH.pmask, CD_SET_DEFAULT, totpoly);
|
||||
CustomData_copy_layout(&mesh->pdata, &pdata, CD_MASK_MESH.pmask, CD_SET_DEFAULT, totpoly);
|
||||
CustomData_copy_data(&mesh->pdata, &pdata, 0, 0, mesh->totpoly);
|
||||
|
||||
mesh->poly_offset_indices = static_cast<int *>(
|
||||
|
|
|
@ -105,7 +105,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
|
|||
|
||||
if (me->totvert) {
|
||||
/* standard data */
|
||||
CustomData_merge(&me->vdata, vdata, CD_MASK_MESH.vmask, CD_SET_DEFAULT, totvert);
|
||||
CustomData_merge_layout(&me->vdata, vdata, CD_MASK_MESH.vmask, CD_SET_DEFAULT, totvert);
|
||||
CustomData_copy_data_named(&me->vdata, vdata, 0, *vertofs, me->totvert);
|
||||
|
||||
/* vertex groups */
|
||||
|
@ -205,7 +205,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
|
|||
}
|
||||
|
||||
if (me->totedge) {
|
||||
CustomData_merge(&me->edata, edata, CD_MASK_MESH.emask, CD_SET_DEFAULT, totedge);
|
||||
CustomData_merge_layout(&me->edata, edata, CD_MASK_MESH.emask, CD_SET_DEFAULT, totedge);
|
||||
CustomData_copy_data_named(&me->edata, edata, 0, *edgeofs, me->totedge);
|
||||
|
||||
for (a = 0; a < me->totedge; a++, edge++) {
|
||||
|
@ -226,7 +226,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
|
|||
}
|
||||
}
|
||||
|
||||
CustomData_merge(&me->ldata, ldata, CD_MASK_MESH.lmask, CD_SET_DEFAULT, totloop);
|
||||
CustomData_merge_layout(&me->ldata, ldata, CD_MASK_MESH.lmask, CD_SET_DEFAULT, totloop);
|
||||
CustomData_copy_data_named(&me->ldata, ldata, 0, *loopofs, me->totloop);
|
||||
|
||||
for (a = 0; a < me->totloop; a++) {
|
||||
|
@ -250,7 +250,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
|
|||
}
|
||||
}
|
||||
|
||||
CustomData_merge(&me->pdata, pdata, CD_MASK_MESH.pmask, CD_SET_DEFAULT, totpoly);
|
||||
CustomData_merge_layout(&me->pdata, pdata, CD_MASK_MESH.pmask, CD_SET_DEFAULT, totpoly);
|
||||
CustomData_copy_data_named(&me->pdata, pdata, 0, *polyofs, me->totpoly);
|
||||
|
||||
/* Apply matmap. In case we don't have material indices yet, create them if more than one
|
||||
|
@ -417,14 +417,6 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* remove tessface to ensure we don't hold references to invalid faces */
|
||||
BKE_mesh_tessface_clear(me);
|
||||
|
||||
/* Clear any run-time data.
|
||||
* Even though this mesh wont typically have run-time data, the Python API can for e.g.
|
||||
* create loop-triangle cache here, which is confusing when left in the mesh, see: #90798. */
|
||||
BKE_mesh_runtime_clear_geometry(me);
|
||||
|
||||
/* new material indices and material array */
|
||||
if (totmat) {
|
||||
matar = static_cast<Material **>(MEM_callocN(sizeof(*matar) * totmat, __func__));
|
||||
|
@ -683,11 +675,8 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
|
|||
/* return to mesh we're merging to */
|
||||
me = static_cast<Mesh *>(ob->data);
|
||||
|
||||
CustomData_free(&me->vdata, me->totvert);
|
||||
CustomData_free(&me->edata, me->totedge);
|
||||
CustomData_free(&me->ldata, me->totloop);
|
||||
CustomData_free(&me->pdata, me->totpoly);
|
||||
MEM_SAFE_FREE(me->poly_offset_indices);
|
||||
BKE_mesh_clear_geometry(me);
|
||||
|
||||
me->poly_offset_indices = poly_offsets;
|
||||
|
||||
me->totvert = totvert;
|
||||
|
|
|
@ -731,7 +731,7 @@ static void add_shapekey_layers(Mesh &mesh_dest, const Mesh &mesh_src)
|
|||
}
|
||||
|
||||
CustomData_add_layer_named_with_data(
|
||||
&mesh_dest.vdata, CD_SHAPEKEY, array, mesh_dest.totvert, kb->name);
|
||||
&mesh_dest.vdata, CD_SHAPEKEY, array, mesh_dest.totvert, kb->name, nullptr);
|
||||
const int ci = CustomData_get_layer_index_n(&mesh_dest.vdata, CD_SHAPEKEY, i);
|
||||
|
||||
mesh_dest.vdata.layers[ci].uid = kb->uid;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue