WIP: Vulkan: Workbench #107886

Closed
Jeroen Bakker wants to merge 88 commits from Jeroen-Bakker:vulkan-draw-manager-workbench into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
48 changed files with 708 additions and 276 deletions
Showing only changes of commit e9d6ee1860 - Show all commits

View File

@ -31,7 +31,8 @@ IF(NOT PYTHON_ROOT_DIR AND NOT $ENV{PYTHON_ROOT_DIR} STREQUAL "")
SET(PYTHON_ROOT_DIR $ENV{PYTHON_ROOT_DIR})
ENDIF()
SET(PYTHON_VERSION 3.10 CACHE STRING "Python Version (major and minor only)")
SET(_PYTHON_VERSION_SUPPORTED 3.10)
SET(PYTHON_VERSION ${_PYTHON_VERSION_SUPPORTED} CACHE STRING "Python Version (major and minor only)")
MARK_AS_ADVANCED(PYTHON_VERSION)
@ -178,8 +179,24 @@ UNSET(_IS_LIB_PATH_DEF)
# handle the QUIETLY and REQUIRED arguments and SET PYTHONLIBSUNIX_FOUND to TRUE IF
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibsUnix DEFAULT_MSG
PYTHON_LIBRARY PYTHON_LIBPATH PYTHON_INCLUDE_DIR PYTHON_INCLUDE_CONFIG_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibsUnix
# NOTE(@ideasman42): Instead of `DEFAULT_MSG` use a custom message because users
# may have newer versions Python and not be using pre-compiled libraries
# (on other UNIX systems or using an esoteric architecture).
# Some Python developers might want to use the newer features of Python too.
# While we could automatically detect and use newer versions but this would result in
# developers using a configuration which isn't officially supported without realizing it.
# So warn that the officially supported Python version is not found and let the developer
# explicitly set the newer version if they wish.
# From a maintenance perspective it's typically not a problem to support newer versions,
# doing so can help ease the process of upgrading too, nevertheless these versions don't
# have the same level of testing & support.
"\
'PYTHON_VERSION=${_PYTHON_VERSION_SUPPORTED}' not found! \
This is the only officially supported version. \
If you wish to use a newer Python version you may set 'PYTHON_VERSION' \
however we do not guarantee full compatibility in this case."
PYTHON_LIBRARY PYTHON_LIBPATH PYTHON_INCLUDE_DIR PYTHON_INCLUDE_CONFIG_DIR)
IF(PYTHONLIBSUNIX_FOUND)
# Assign cache items
@ -215,6 +232,7 @@ IF(PYTHONLIBSUNIX_FOUND)
ENDIF()
UNSET(_PYTHON_ABI_FLAGS)
UNSET(_PYTHON_VERSION_SUPPORTED)
UNSET(_python_SEARCH_DIRS)
MARK_AS_ADVANCED(

View File

@ -363,7 +363,11 @@ windows_find_package(Freetype REQUIRED)
if(WITH_FFTW3)
set(FFTW3 ${LIBDIR}/fftw3)
set(FFTW3_LIBRARIES ${FFTW3}/lib/libfftw.lib)
if(EXISTS ${FFTW3}/lib/libfftw3-3.lib) # 3.6 libraries
set(FFTW3_LIBRARIES ${FFTW3}/lib/libfftw3-3.lib ${FFTW3}/lib/libfftw3f.lib)
else()
set(FFTW3_LIBRARIES ${FFTW3}/lib/libfftw.lib) # 3.5 Libraries
endif()
set(FFTW3_INCLUDE_DIRS ${FFTW3}/include)
set(FFTW3_LIBPATH ${FFTW3}/lib)
endif()

View File

@ -7,7 +7,7 @@
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:docname="blender_icons.svg"
version="1.0"
inkscape:version="1.2 (dc2aeda, 2022-05-15)"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
sodipodi:version="0.32"
id="svg2"
height="640"
@ -27,7 +27,6 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@ -42,16 +41,16 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1728"
inkscape:window-height="1051"
inkscape:window-width="3840"
inkscape:window-height="2036"
id="namedview34335"
showgrid="false"
inkscape:zoom="1.2495612"
inkscape:cx="196.46897"
inkscape:cy="320.51252"
inkscape:window-x="767"
inkscape:window-y="120"
inkscape:window-maximized="0"
inkscape:zoom="2"
inkscape:cx="180.75"
inkscape:cy="338.5"
inkscape:window-x="-12"
inkscape:window-y="-12"
inkscape:window-maximized="1"
inkscape:current-layer="layer8"
inkscape:showpageshadow="2"
inkscape:deskcolor="#808080" />
@ -7148,6 +7147,10 @@
sodipodi:nodetypes="ccccccccccccc" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="J-23" />
<g
inkscape:groupmode="layer"
id="layer8"
@ -15195,6 +15198,103 @@
id="circle8021-5"
inkscape:connector-curvature="0" />
</g>
<g
id="g13706"
inkscape:label="J-23"
style="display:inline;enable-background:new">
<g
id="g17336"
style="display:inline;opacity:0.7;stroke-width:1.44731;stroke-dasharray:none;enable-background:new"
transform="matrix(0.6914962,0,0,0.6915053,144.53231,65.869882)">
<g
id="g17408"
transform="translate(-1.1860055,2.3126067)"
style="stroke-width:1.44731;stroke-dasharray:none">
<path
style="fill:none;stroke:#ffffff;stroke-width:1.44731;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 471.48986,207.6 v -6.605"
id="path13630"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ffffff;stroke-width:1.44731;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
d="m 469.75403,202.73197 1.73583,-1.73697 1.73628,1.73697"
id="path13701"
sodipodi:nodetypes="ccc" />
</g>
<g
id="g17404"
transform="rotate(90,473.15911,208.96873)"
style="stroke-width:1.44731;stroke-dasharray:none">
<path
style="display:inline;fill:none;stroke:#ffffff;stroke-width:1.44731;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
d="M 475.88023,210.00984 V 203.9052"
id="path13630-5"
sodipodi:nodetypes="cc" />
<path
style="display:inline;fill:none;stroke:#ffffff;stroke-width:1.44731;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
d="m 474.14424,205.64156 1.73599,-1.73636 1.73612,1.73636"
id="path13701-0"
sodipodi:nodetypes="ccc" />
</g>
<circle
style="display:inline;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.44731;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
id="path12466"
cx="470.30371"
cy="211.68971"
r="1.8006321" />
</g>
<g
id="g17336-1"
style="display:inline;stroke-width:1.44731;stroke-dasharray:none;enable-background:new"
transform="matrix(0.6914962,0,0,0.6915053,150.788,59.912101)">
<g
id="g17408-1"
transform="translate(-1.1860055,2.3126067)"
style="stroke-width:1.44731;stroke-dasharray:none">
<path
style="fill:none;stroke:#ffffff;stroke-width:1.44731;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 471.48986,207.6 v -6.605"
id="path13630-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ffffff;stroke-width:1.44731;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
d="m 469.75403,202.73197 1.73583,-1.73697 1.73628,1.73697"
id="path13701-4"
sodipodi:nodetypes="ccc" />
</g>
<g
id="g17404-6"
transform="rotate(90,473.15911,208.96873)"
style="stroke-width:1.44731;stroke-dasharray:none">
<path
style="display:inline;fill:none;stroke:#ffffff;stroke-width:1.44731;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
d="M 475.88023,210.00984 V 203.9052"
id="path13630-5-8"
sodipodi:nodetypes="cc" />
<path
style="display:inline;fill:none;stroke:#ffffff;stroke-width:1.44731;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
d="m 474.14424,205.64156 1.73599,-1.73636 1.73612,1.73636"
id="path13701-0-3"
sodipodi:nodetypes="ccc" />
</g>
<circle
style="display:inline;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.44731;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
id="path12466-6"
cx="470.30371"
cy="211.68971"
r="1.8006321" />
</g>
<path
style="display:inline;opacity:0.7;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.00082;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
d="m 473.31787,208.67619 0.4302,-0.44676"
id="path24883-4"
sodipodi:nodetypes="cc" />
<path
style="display:inline;opacity:0.7;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.00082;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
d="m 471.76625,210.24534 0.4302,-0.44676"
id="path24883-4-0"
sodipodi:nodetypes="cc" />
</g>
<g
style="display:inline;fill:#ffffff;enable-background:new"
id="g14253"

Before

Width:  |  Height:  |  Size: 2.6 MiB

After

Width:  |  Height:  |  Size: 2.6 MiB

View File

@ -614,6 +614,7 @@ class NODE_MT_category_GEO_VOLUME(Menu):
node_add_menu.add_node_type(layout, "GeometryNodeMeanFilterSDFVolume")
node_add_menu.add_node_type(layout, "GeometryNodeOffsetSDFVolume")
node_add_menu.add_node_type(layout, "GeometryNodeSDFVolumeSphere")
node_add_menu.add_node_type(layout, "GeometryNodeInputSignedDistance")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)

View File

@ -435,7 +435,9 @@ class IMAGE_MT_uvs(Menu):
layout.separator()
layout.operator_context = 'INVOKE_DEFAULT'
layout.operator("uv.pack_islands")
layout.operator_context = 'EXEC_REGION_WIN'
layout.operator("uv.average_islands_scale")
layout.separator()

View File

@ -1587,6 +1587,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
/* Function nodes use the range starting at 1200. */
#define GEO_NODE_SIMULATION_INPUT 2100
#define GEO_NODE_SIMULATION_OUTPUT 2101
#define GEO_NODE_INPUT_SIGNED_DISTANCE 2102
/** \} */

View File

@ -67,6 +67,8 @@
#include "atomic_ops.h"
#include "lib_intern.h"
//#define DEBUG_TIME
#ifdef DEBUG_TIME
@ -439,7 +441,7 @@ void BKE_lib_id_expand_local(Main *bmain, ID *id, const int flags)
/**
* Ensure new (copied) ID is fully made local.
*/
static void lib_id_copy_ensure_local(Main *bmain, const ID *old_id, ID *new_id, const int flags)
void lib_id_copy_ensure_local(Main *bmain, const ID *old_id, ID *new_id, const int flags)
{
if (ID_IS_LINKED(old_id)) {
BKE_lib_id_expand_local(bmain, new_id, flags);

View File

@ -7,6 +7,24 @@
#pragma once
#include "BKE_lib_remap.h"
#ifdef __cplusplus
extern "C" {
#endif
extern BKE_library_free_notifier_reference_cb free_notifier_reference_cb;
extern BKE_library_remap_editor_id_reference_cb remap_editor_id_reference_cb;
struct ID;
struct Main;
void lib_id_copy_ensure_local(struct Main *bmain,
const struct ID *old_id,
struct ID *new_id,
const int flags);
#ifdef __cplusplus
}
#endif

View File

@ -61,6 +61,8 @@
#include "atomic_ops.h"
#include "lib_intern.h"
#define OVERRIDE_AUTO_CHECK_DELAY 0.2 /* 200ms between auto-override checks. */
//#define DEBUG_OVERRIDE_TIMEIT
@ -277,9 +279,11 @@ static ID *lib_override_library_create_from(Main *bmain,
id_us_min(local_id);
/* TODO: Handle this properly in LIB_NO_MAIN case as well (i.e. resync case). Or offload to
* generic ID copy code? */
if ((lib_id_copy_flags & LIB_ID_CREATE_NO_MAIN) == 0) {
local_id->lib = owner_library;
* generic ID copy code? Would probably be better to have a version of #BKE_id_copy_ex that takes
* an extra `target_lib` parameter. */
local_id->lib = owner_library;
if ((lib_id_copy_flags & LIB_ID_CREATE_NO_MAIN) != 0 && owner_library == nullptr) {
lib_id_copy_ensure_local(bmain, reference_id, local_id, 0);
}
BKE_lib_override_library_init(local_id, reference_id);

View File

@ -176,15 +176,15 @@ TEST(math_rotation, mat3_normalized_to_quat_fast_degenerate)
* particular matrix was taken from a production file of Pet Projects that
* caused problems. */
const float input[3][3] = {
{0.970698, -0.000001, -0.253102},
{-0.213197, 1.000000, -0.363476},
{0.110873, -0.000002, 0.896563},
{1.0000000000, -0.0000006315, -0.0000000027},
{0.0000009365, 1.0000000000, -0.0000000307},
{0.0000001964, 0.2103530765, 0.9776254892},
};
const float expect_quat[4] = {
0.989793062210083,
-0.09302811324596405,
0.0931563451886177,
0.05456572398543358,
0.99860459566116333,
-0.052810292690992355,
4.9985139582986449e-08,
-3.93654971730939e-07,
};
ASSERT_FLOAT_EQ(1.0f, dot_qtqt(expect_quat, expect_quat))
<< "expected quaternion should be normal";

View File

@ -453,15 +453,14 @@ void OutputOpenExrMultiLayerOperation::update_memory_buffer_partial(MemoryBuffer
const rcti &area,
Span<MemoryBuffer *> inputs)
{
const MemoryBuffer *input_image = inputs[0];
for (int i = 0; i < layers_.size(); i++) {
OutputOpenExrLayer &layer = layers_[i];
int layer_num_channels = COM_data_type_num_channels(layer.datatype);
if (layer.output_buffer) {
MemoryBuffer output_buf(layer.output_buffer,
COM_data_type_num_channels(layer.datatype),
this->get_width(),
this->get_height());
output_buf.copy_from(input_image, area);
MemoryBuffer output_buf(
layer.output_buffer, layer_num_channels, this->get_width(), this->get_height());
/* Input node always has 4 channels. Not all are needed depending on datatype. */
output_buf.copy_from(inputs[i], area, 0, layer_num_channels, 0);
}
}
}

View File

@ -327,6 +327,7 @@ void postEditBoneDuplicate(struct ListBase *editbones, Object *ob)
if (!ebone_dst) {
ebone_dst = ED_armature_ebone_get_mirrored(editbones, ebone_src);
}
if (ebone_dst) {
BLI_ghash_insert(name_map, ebone_src->name, ebone_dst->name);
}
@ -334,22 +335,28 @@ void postEditBoneDuplicate(struct ListBase *editbones, Object *ob)
LISTBASE_FOREACH (EditBone *, ebone_src, editbones) {
EditBone *ebone_dst = ebone_src->temp.ebone;
if (ebone_dst) {
bPoseChannel *pchan_src = BKE_pose_channel_find_name(ob->pose, ebone_src->name);
if (pchan_src) {
bPoseChannel *pchan_dst = BKE_pose_channel_find_name(ob->pose, ebone_dst->name);
if (pchan_dst) {
if (pchan_src->custom_tx) {
pchan_dst->custom_tx = pchan_duplicate_map(ob->pose, name_map, pchan_src->custom_tx);
}
if (pchan_src->bbone_prev) {
pchan_dst->bbone_prev = pchan_duplicate_map(ob->pose, name_map, pchan_src->bbone_prev);
}
if (pchan_src->bbone_next) {
pchan_dst->bbone_next = pchan_duplicate_map(ob->pose, name_map, pchan_src->bbone_next);
}
}
}
if (!ebone_dst) {
continue;
}
bPoseChannel *pchan_src = BKE_pose_channel_find_name(ob->pose, ebone_src->name);
if (!pchan_src) {
continue;
}
bPoseChannel *pchan_dst = BKE_pose_channel_find_name(ob->pose, ebone_dst->name);
if (!pchan_dst) {
continue;
}
if (pchan_src->custom_tx) {
pchan_dst->custom_tx = pchan_duplicate_map(ob->pose, name_map, pchan_src->custom_tx);
}
if (pchan_src->bbone_prev) {
pchan_dst->bbone_prev = pchan_duplicate_map(ob->pose, name_map, pchan_src->bbone_prev);
}
if (pchan_src->bbone_next) {
pchan_dst->bbone_next = pchan_duplicate_map(ob->pose, name_map, pchan_src->bbone_next);
}
}
@ -1120,71 +1127,80 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
bArmature *arm = obedit->data;
EditBone *ebone_iter;
/* The beginning of the duplicated mirrored bones in the edbo list */
EditBone *ebone_first_dupe = NULL;
Object *obedit = objects[ob_index];
bArmature *arm = obedit->data;
ED_armature_edit_sync_selection(arm->edbo); /* XXX why is this needed? */
preEditBoneDuplicate(arm->edbo);
/* Select mirrored bones */
/* Deselect ebones depending on input axis and direction.
* A symmetrizable selection contains selected ebones of the input direction
* and unique selected bones with an unique flippable name.
*
* Storing temp ptrs to mirrored unselected ebones. */
for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
if (EBONE_VISIBLE(arm, ebone_iter) && (ebone_iter->flag & BONE_SELECTED)) {
char name_flip[MAXBONENAME];
if (!(EBONE_VISIBLE(arm, ebone_iter) && (ebone_iter->flag & BONE_SELECTED))) {
/* Skipping invisible selected bones. */
continue;
}
BLI_string_flip_side_name(name_flip, ebone_iter->name, false, sizeof(name_flip));
char name_flip[MAXBONENAME];
if (ebone_iter == NULL) {
continue;
}
if (STREQ(name_flip, ebone_iter->name)) {
/* if the name matches, we don't have the potential to be mirrored, just skip */
ebone_iter->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
}
else {
EditBone *ebone = ED_armature_ebone_find_name(arm->edbo, name_flip);
BLI_string_flip_side_name(name_flip, ebone_iter->name, false, sizeof(name_flip));
if (ebone) {
if ((ebone->flag & BONE_SELECTED) == 0) {
/* simple case, we're selected, the other bone isn't! */
ebone_iter->temp.ebone = ebone;
}
else {
/* complicated - choose which direction to copy */
float axis_delta;
if (STREQ(name_flip, ebone_iter->name)) {
/* Skipping ebones without flippable as they don't have the potential to be mirrored. */
ebone_iter->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
continue;
}
axis_delta = ebone->head[axis] - ebone_iter->head[axis];
if (axis_delta == 0.0f) {
axis_delta = ebone->tail[axis] - ebone_iter->tail[axis];
}
EditBone *ebone = ED_armature_ebone_find_name(arm->edbo, name_flip);
if (axis_delta == 0.0f) {
/* Both mirrored bones exist and point to each other and overlap exactly.
*
* in this case there's no well defined solution, so de-select both and skip.
*/
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
ebone_iter->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
}
else {
EditBone *ebone_src, *ebone_dst;
if (((axis_delta < 0.0f) ? -1 : 1) == direction) {
ebone_src = ebone;
ebone_dst = ebone_iter;
}
else {
ebone_src = ebone_iter;
ebone_dst = ebone;
}
if (!ebone) {
/* The ebone_iter is unique and mirrorable. */
continue;
}
ebone_src->temp.ebone = ebone_dst;
ebone_dst->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
}
}
if (ebone->flag & BONE_SELECTED) {
/* The mirrored ebone and the ebone_iter are selected.
* Deselect based on the input direction and axis. */
float axis_delta;
axis_delta = ebone->head[axis] - ebone_iter->head[axis];
if (axis_delta == 0.0f) {
/* The ebone heads are overlapping. */
axis_delta = ebone->tail[axis] - ebone_iter->tail[axis];
if (axis_delta == 0.0f) {
/* Both mirrored bones point to each other and overlap exactly.
* In this case there's no well defined solution, so de-select both and skip. */
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
ebone_iter->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
continue;
}
}
/* Deselect depending on direction. */
if (((axis_delta < 0.0f) ? -1 : 1) == direction) {
/* Don't store temp ptr if the iter_bone gets deselected.
* In this case, the ebone.temp should point to the ebone_iter. */
ebone_iter->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
continue;
}
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
}
/* Set temp pointer to mirrored ebones */
ebone_iter->temp.ebone = ebone;
}
/* Find the selected bones and duplicate them as needed, with mirrored name. */
@ -1206,11 +1222,12 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
ebone_iter->temp.ebone->inherit_scale_mode = ebone_iter->inherit_scale_mode;
continue;
}
char name_flip[MAXBONENAME];
BLI_string_flip_side_name(name_flip, ebone_iter->name, false, sizeof(name_flip));
/* bones must have a side-suffix */
/* mirrored bones must have a side-suffix */
if (!STREQ(name_flip, ebone_iter->name)) {
EditBone *ebone;
@ -1254,8 +1271,8 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
*/
if (ebone->head[axis] != 0.0f) {
/* The mirrored bone doesn't start on the mirror axis, so assume that this one should
* not be connected to the old parent */
/* The mirrored bone doesn't start on the mirror axis, so assume that this one
* should not be connected to the old parent */
ebone->flag &= ~BONE_CONNECTED;
}
}

View File

@ -508,6 +508,7 @@ set(ICON_NAMES
ipo_ease_out
ipo_ease_in_out
normalize_fcurves
orientation_parent
vertexsel
edgesel
facesel

View File

@ -56,24 +56,6 @@ void ED_gizmotypes_snap_3d_flag_set(struct wmGizmo *gz, int flag)
snap_state->flag |= flag;
}
void ED_gizmotypes_snap_3d_flag_clear(struct wmGizmo *gz, int flag)
{
V3DSnapCursorState *snap_state = ((SnapGizmo3D *)gz)->snap_state;
snap_state->flag &= ~flag;
}
bool ED_gizmotypes_snap_3d_flag_test(struct wmGizmo *gz, int flag)
{
V3DSnapCursorState *snap_state = ((SnapGizmo3D *)gz)->snap_state;
return (snap_state->flag & flag) != 0;
}
bool ED_gizmotypes_snap_3d_invert_snap_get(struct wmGizmo *UNUSED(gz))
{
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
return snap_data->is_snap_invert;
}
bool ED_gizmotypes_snap_3d_is_enabled(const wmGizmo *UNUSED(gz))
{
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
@ -135,7 +117,7 @@ static V3DSnapCursorState *gizmo_snap_state_from_rna_get(struct PointerRNA *ptr)
return snap_gizmo->snap_state;
}
return ED_view3d_cursor_snap_state_get();
return ED_view3d_cursor_snap_state_active_get();
}
static int gizmo_snap_rna_snap_elements_force_get_fn(struct PointerRNA *ptr,
@ -168,7 +150,7 @@ static void gizmo_snap_rna_prevpoint_set_fn(struct PointerRNA *ptr,
const float *values)
{
V3DSnapCursorState *snap_state = gizmo_snap_state_from_rna_get(ptr);
ED_view3d_cursor_snap_prevpoint_set(snap_state, values);
ED_view3d_cursor_snap_state_prevpoint_set(snap_state, values);
}
static void gizmo_snap_rna_location_get_fn(struct PointerRNA *UNUSED(ptr),
@ -212,7 +194,7 @@ static void gizmo_snap_rna_snap_elem_index_get_fn(struct PointerRNA *UNUSED(ptr)
static void snap_cursor_free(SnapGizmo3D *snap_gizmo)
{
if (snap_gizmo->snap_state) {
ED_view3d_cursor_snap_deactive(snap_gizmo->snap_state);
ED_view3d_cursor_snap_state_free(snap_gizmo->snap_state);
snap_gizmo->snap_state = NULL;
}
}
@ -242,7 +224,7 @@ static bool snap_cursor_poll(ARegion *region, void *data)
static void snap_cursor_init(SnapGizmo3D *snap_gizmo)
{
snap_gizmo->snap_state = ED_view3d_cursor_snap_active();
snap_gizmo->snap_state = ED_view3d_cursor_snap_state_create();
snap_gizmo->snap_state->draw_point = true;
snap_gizmo->snap_state->draw_plane = false;
@ -270,7 +252,10 @@ static void snap_gizmo_draw(const bContext *UNUSED(C), wmGizmo *gz)
if (snap_gizmo->snap_state == NULL) {
snap_cursor_init(snap_gizmo);
}
/* All drawing is handled at the paint cursor. */
/* All drawing is handled at the paint cursor.
* Therefore, make sure that the #V3DSnapCursorState is the one of the gizmo being drawn. */
ED_view3d_cursor_snap_state_active_set(snap_gizmo->snap_state);
}
static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2])

View File

@ -248,10 +248,7 @@ struct SnapObjectContext *ED_gizmotypes_snap_3d_context_ensure(struct Scene *sce
struct wmGizmo *gz);
void ED_gizmotypes_snap_3d_flag_set(struct wmGizmo *gz, int flag);
void ED_gizmotypes_snap_3d_flag_clear(struct wmGizmo *gz, int flag);
bool ED_gizmotypes_snap_3d_flag_test(struct wmGizmo *gz, int flag);
bool ED_gizmotypes_snap_3d_invert_snap_get(struct wmGizmo *gz);
bool ED_gizmotypes_snap_3d_is_enabled(const struct wmGizmo *gz);
void ED_gizmotypes_snap_3d_data_get(const struct bContext *C,

View File

@ -336,10 +336,12 @@ typedef struct V3DSnapCursorState {
} V3DSnapCursorState;
void ED_view3d_cursor_snap_state_default_set(V3DSnapCursorState *state);
V3DSnapCursorState *ED_view3d_cursor_snap_state_get(void);
V3DSnapCursorState *ED_view3d_cursor_snap_active(void);
void ED_view3d_cursor_snap_deactive(V3DSnapCursorState *state);
void ED_view3d_cursor_snap_prevpoint_set(V3DSnapCursorState *state, const float prev_point[3]);
V3DSnapCursorState *ED_view3d_cursor_snap_state_active_get(void);
void ED_view3d_cursor_snap_state_active_set(V3DSnapCursorState *state);
V3DSnapCursorState *ED_view3d_cursor_snap_state_create(void);
void ED_view3d_cursor_snap_state_free(V3DSnapCursorState *state);
void ED_view3d_cursor_snap_state_prevpoint_set(V3DSnapCursorState *state,
const float prev_point[3]);
void ED_view3d_cursor_snap_data_update(V3DSnapCursorState *state,
const struct bContext *C,
int x,

View File

@ -618,7 +618,7 @@ DEF_ICON(IPO_EASE_IN)
DEF_ICON(IPO_EASE_OUT)
DEF_ICON(IPO_EASE_IN_OUT)
DEF_ICON(NORMALIZE_FCURVES)
DEF_ICON_BLANK(635)
DEF_ICON(ORIENTATION_PARENT)
DEF_ICON_BLANK(636)
DEF_ICON_BLANK(637)
DEF_ICON_BLANK(638)

View File

@ -779,6 +779,9 @@ static bConstraint *edit_constraint_property_get(bContext *C, wmOperator *op, Ob
if (owner == EDIT_CONSTRAINT_OWNER_BONE) {
list = ED_object_pose_constraint_list(C);
if (!list) {
return NULL;
}
}
else {
list = &ob->constraints;

View File

@ -519,7 +519,7 @@ static void view3d_ob_drop_draw_activate(struct wmDropBox *drop, wmDrag *drag)
return;
}
state = static_cast<V3DSnapCursorState *>(ED_view3d_cursor_snap_active());
state = static_cast<V3DSnapCursorState *>(ED_view3d_cursor_snap_state_create());
drop->draw_data = state;
state->draw_plane = true;
@ -547,7 +547,7 @@ static void view3d_ob_drop_draw_deactivate(struct wmDropBox *drop, wmDrag * /*dr
{
V3DSnapCursorState *state = static_cast<V3DSnapCursorState *>(drop->draw_data);
if (state) {
ED_view3d_cursor_snap_deactive(state);
ED_view3d_cursor_snap_state_free(state);
drop->draw_data = nullptr;
}
}
@ -781,7 +781,7 @@ static void view3d_ob_drop_copy_local_id(bContext * /*C*/, wmDrag *drag, wmDropB
/* Don't duplicate ID's which were just imported. Only do that for existing, local IDs. */
BLI_assert(drag->type != WM_DRAG_ASSET);
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
float obmat_final[4][4];
view3d_ob_drop_matrix_from_snap(snap_state, (Object *)id, obmat_final);

View File

@ -829,7 +829,7 @@ static bool v3d_cursor_snap_poll_fn(bContext *C)
};
/* Call this callback last and don't reuse the `state` as the caller can free the cursor. */
V3DSnapCursorState *state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *state = ED_view3d_cursor_snap_state_active_get();
if (state->poll && !state->poll(region, state->poll_data)) {
return false;
}
@ -840,7 +840,7 @@ static bool v3d_cursor_snap_poll_fn(bContext *C)
static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(customdata))
{
SnapCursorDataIntern *data_intern = &g_data_intern;
V3DSnapCursorState *state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *state = ED_view3d_cursor_snap_state_active_get();
V3DSnapCursorData *snap_data = &data_intern->snap_data;
wmWindowManager *wm = CTX_wm_manager(C);
@ -902,7 +902,7 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust
/** \} */
V3DSnapCursorState *ED_view3d_cursor_snap_state_get(void)
V3DSnapCursorState *ED_view3d_cursor_snap_state_active_get(void)
{
SnapCursorDataIntern *data_intern = &g_data_intern;
if (BLI_listbase_is_empty(&data_intern->state_intern)) {
@ -911,6 +911,26 @@ V3DSnapCursorState *ED_view3d_cursor_snap_state_get(void)
return &((SnapStateIntern *)data_intern->state_intern.last)->snap_state;
}
void ED_view3d_cursor_snap_state_active_set(V3DSnapCursorState *state)
{
if (state == &g_data_intern.state_default) {
BLI_assert_unreachable();
return;
}
SnapStateIntern *state_intern = STATE_INTERN_GET(state);
if (state_intern == (SnapStateIntern *)g_data_intern.state_intern.last) {
return;
}
if (!BLI_remlink_safe(&g_data_intern.state_intern, state_intern)) {
BLI_assert_unreachable();
return;
}
BLI_addtail(&g_data_intern.state_intern, state_intern);
}
static void v3d_cursor_snap_activate(void)
{
SnapCursorDataIntern *data_intern = &g_data_intern;
@ -964,7 +984,7 @@ void ED_view3d_cursor_snap_state_default_set(V3DSnapCursorState *state)
g_data_intern.state_default.poll_data = NULL;
}
V3DSnapCursorState *ED_view3d_cursor_snap_active(void)
V3DSnapCursorState *ED_view3d_cursor_snap_state_create(void)
{
SnapCursorDataIntern *data_intern = &g_data_intern;
if (!data_intern->handle) {
@ -978,7 +998,7 @@ V3DSnapCursorState *ED_view3d_cursor_snap_active(void)
return (V3DSnapCursorState *)&state_intern->snap_state;
}
void ED_view3d_cursor_snap_deactive(V3DSnapCursorState *state)
void ED_view3d_cursor_snap_state_free(V3DSnapCursorState *state)
{
SnapCursorDataIntern *data_intern = &g_data_intern;
if (BLI_listbase_is_empty(&data_intern->state_intern)) {
@ -993,11 +1013,12 @@ void ED_view3d_cursor_snap_deactive(V3DSnapCursorState *state)
}
}
void ED_view3d_cursor_snap_prevpoint_set(V3DSnapCursorState *state, const float prev_point[3])
void ED_view3d_cursor_snap_state_prevpoint_set(V3DSnapCursorState *state,
const float prev_point[3])
{
SnapCursorDataIntern *data_intern = &g_data_intern;
if (!state) {
state = ED_view3d_cursor_snap_state_get();
state = ED_view3d_cursor_snap_state_active_get();
}
if (prev_point) {
copy_v3_v3(data_intern->prevpoint_stack, prev_point);
@ -1023,7 +1044,7 @@ void ED_view3d_cursor_snap_data_update(V3DSnapCursorState *state,
View3D *v3d = CTX_wm_view3d(C);
if (!state) {
state = ED_view3d_cursor_snap_state_get();
state = ED_view3d_cursor_snap_state_active_get();
}
v3d_cursor_snap_update(state, C, wm, depsgraph, scene, region, v3d, x, y);
}

View File

@ -708,7 +708,7 @@ static bool view3d_interactive_add_calc_snap(bContext *UNUSED(C),
static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEvent *event)
{
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
const int plane_axis = snap_state->plane_axis;
const enum ePlace_SnapTo snap_to = RNA_enum_get(op->ptr, "snap_target");
@ -726,7 +726,7 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
ipd->launch_event = WM_userdef_event_type_from_keymap_type(event->type);
V3DSnapCursorState *snap_state_new = ED_view3d_cursor_snap_active();
V3DSnapCursorState *snap_state_new = ED_view3d_cursor_snap_state_create();
if (snap_state_new) {
ipd->snap_state = snap_state = snap_state_new;
@ -755,7 +755,7 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
C, event, ipd->co_src, ipd->matrix_orient, &ipd->use_snap, &ipd->is_snap_invert) != 0;
snap_state->draw_plane = false;
ED_view3d_cursor_snap_prevpoint_set(snap_state, ipd->co_src);
ED_view3d_cursor_snap_state_prevpoint_set(snap_state, ipd->co_src);
ipd->orient_axis = plane_axis;
for (int i = 0; i < 2; i++) {
@ -910,7 +910,7 @@ static void view3d_interactive_add_exit(bContext *C, wmOperator *op)
UNUSED_VARS(C);
struct InteractivePlaceData *ipd = op->customdata;
ED_view3d_cursor_snap_deactive(ipd->snap_state);
ED_view3d_cursor_snap_state_free(ipd->snap_state);
if (ipd->region != NULL) {
if (ipd->draw_handle_view != NULL) {
@ -1036,7 +1036,7 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
if (ipd->step_index == STEP_BASE) {
if (ELEM(event->type, ipd->launch_event, LEFTMOUSE)) {
if (event->val == KM_RELEASE) {
ED_view3d_cursor_snap_prevpoint_set(ipd->snap_state, ipd->co_src);
ED_view3d_cursor_snap_state_prevpoint_set(ipd->snap_state, ipd->co_src);
/* Set secondary plane. */
@ -1265,7 +1265,7 @@ static bool view3d_interactive_add_poll(bContext *C)
static int idp_rna_plane_axis_get_fn(struct PointerRNA *UNUSED(ptr),
struct PropertyRNA *UNUSED(prop))
{
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
return snap_state->plane_axis;
}
@ -1273,7 +1273,7 @@ static void idp_rna_plane_axis_set_fn(struct PointerRNA *UNUSED(ptr),
struct PropertyRNA *UNUSED(prop),
int value)
{
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
snap_state->plane_axis = (short)value;
ED_view3d_cursor_snap_state_default_set(snap_state);
}
@ -1281,7 +1281,7 @@ static void idp_rna_plane_axis_set_fn(struct PointerRNA *UNUSED(ptr),
static int idp_rna_plane_depth_get_fn(struct PointerRNA *UNUSED(ptr),
struct PropertyRNA *UNUSED(prop))
{
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
return snap_state->plane_depth;
}
@ -1289,7 +1289,7 @@ static void idp_rna_plane_depth_set_fn(struct PointerRNA *UNUSED(ptr),
struct PropertyRNA *UNUSED(prop),
int value)
{
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
snap_state->plane_depth = value;
ED_view3d_cursor_snap_state_default_set(snap_state);
}
@ -1297,7 +1297,7 @@ static void idp_rna_plane_depth_set_fn(struct PointerRNA *UNUSED(ptr),
static int idp_rna_plane_orient_get_fn(struct PointerRNA *UNUSED(ptr),
struct PropertyRNA *UNUSED(prop))
{
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
return snap_state->plane_orient;
}
@ -1305,7 +1305,7 @@ static void idp_rna_plane_orient_set_fn(struct PointerRNA *UNUSED(ptr),
struct PropertyRNA *UNUSED(prop),
int value)
{
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
snap_state->plane_orient = value;
ED_view3d_cursor_snap_state_default_set(snap_state);
}
@ -1313,7 +1313,7 @@ static void idp_rna_plane_orient_set_fn(struct PointerRNA *UNUSED(ptr),
static int idp_rna_snap_target_get_fn(struct PointerRNA *UNUSED(ptr),
struct PropertyRNA *UNUSED(prop))
{
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
if (snap_state->snap_elem_force == SCE_SNAP_MODE_NONE) {
return PLACE_SNAP_TO_DEFAULT;
}
@ -1333,7 +1333,7 @@ static void idp_rna_snap_target_set_fn(struct PointerRNA *UNUSED(ptr),
snap_mode = SCE_SNAP_MODE_GEOM;
}
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
snap_state->snap_elem_force = snap_mode;
ED_view3d_cursor_snap_state_default_set(snap_state);
}
@ -1341,7 +1341,7 @@ static void idp_rna_snap_target_set_fn(struct PointerRNA *UNUSED(ptr),
static bool idp_rna_use_plane_axis_auto_get_fn(struct PointerRNA *UNUSED(ptr),
struct PropertyRNA *UNUSED(prop))
{
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
return snap_state->use_plane_axis_auto;
}
@ -1349,7 +1349,7 @@ static void idp_rna_use_plane_axis_auto_set_fn(struct PointerRNA *UNUSED(ptr),
struct PropertyRNA *UNUSED(prop),
bool value)
{
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_active_get();
snap_state->use_plane_axis_auto = value;
ED_view3d_cursor_snap_state_default_set(snap_state);
}
@ -1523,7 +1523,7 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
static void preview_plane_free_fn(void *customdata)
{
V3DSnapCursorState *snap_state = customdata;
ED_view3d_cursor_snap_deactive(snap_state);
ED_view3d_cursor_snap_state_free(snap_state);
}
static bool snap_cursor_poll(ARegion *region, void *data)
@ -1537,7 +1537,7 @@ static bool snap_cursor_poll(ARegion *region, void *data)
static void WIDGETGROUP_placement_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_active();
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_create();
if (snap_state) {
snap_state->poll = snap_cursor_poll;
snap_state->poll_data = gzgroup->type;

View File

@ -18,6 +18,8 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_global.h"
#include "BLI_array.hh"
#include "BLI_convexhull_2d.h"
#include "BLI_linklist.h"
@ -59,6 +61,7 @@
#include "ED_image.h"
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_undo.h"
#include "ED_uvedit.h"
#include "ED_view3d.h"
@ -169,6 +172,14 @@ void blender::geometry::UVPackIsland_Params::setUDIMOffsetFromSpaceImage(const S
}
/** \} */
bool blender::geometry::UVPackIsland_Params::isCancelled() const
{
if (stop) {
return *stop;
}
return false;
}
/* -------------------------------------------------------------------- */
/** \name Parametrizer Conversion
* \{ */
@ -1141,6 +1152,7 @@ static bool island_has_pins(const Scene *scene,
* This is needed to perform UV packing on objects that aren't in edit-mode.
* \param udim_source_closest: UDIM source SpaceImage.
* \param original_selection: Pack to original selection.
* \param notify_wm: Notify the WM of any changes. (UI thread only.)
* \param params: Parameters and options to pass to the packing engine.
*/
static void uvedit_pack_islands_multi(const Scene *scene,
@ -1149,6 +1161,7 @@ static void uvedit_pack_islands_multi(const Scene *scene,
BMesh **bmesh_override,
const SpaceImage *udim_source_closest,
const bool original_selection,
const bool notify_wm,
blender::geometry::UVPackIsland_Params *params)
{
blender::Vector<FaceIsland *> island_vector;
@ -1271,6 +1284,7 @@ static void uvedit_pack_islands_multi(const Scene *scene,
BLI_memarena_free(arena);
const float scale = pack_islands(pack_island_vector, *params);
const bool is_cancelled = params->isCancelled();
float base_offset[2] = {0.0f, 0.0f};
copy_v2_v2(base_offset, params->udim_base_offset);
@ -1309,7 +1323,10 @@ static void uvedit_pack_islands_multi(const Scene *scene,
float matrix[2][2];
float matrix_inverse[2][2];
float pre_translate[2];
for (int64_t i : pack_island_vector.index_range()) {
for (const int64_t i : pack_island_vector.index_range()) {
if (is_cancelled) {
continue;
}
blender::geometry::PackIsland *pack_island = pack_island_vector[i];
FaceIsland *island = island_vector[pack_island->caller_index];
const float island_scale = pack_island->can_scale_(*params) ? scale : 1.0f;
@ -1339,16 +1356,21 @@ static void uvedit_pack_islands_multi(const Scene *scene,
pre_translate[1] = selection_min_co[1] / rescale;
island_uv_transform(island, matrix, pre_translate);
}
}
for (const int64_t i : pack_island_vector.index_range()) {
blender::geometry::PackIsland *pack_island = pack_island_vector[i];
/* Cleanup memory. */
pack_island_vector[i] = nullptr;
delete pack_island;
}
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data);
if (notify_wm && !is_cancelled) {
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data);
}
}
for (FaceIsland *island : island_vector) {
@ -1361,6 +1383,9 @@ static void uvedit_pack_islands_multi(const Scene *scene,
/** \name Pack UV Islands Operator
* \{ */
/* TODO: support this, interaction with the job-system needs to be handled carefully. */
// #define USE_INTERACTIVE_PACK
/* Packing targets. */
enum {
PACK_UDIM_SRC_CLOSEST = 0,
@ -1368,6 +1393,70 @@ enum {
PACK_ORIGINAL_AABB,
};
struct UVPackIslandsData {
wmWindowManager *wm;
const Scene *scene;
Object **objects;
uint objects_len;
const SpaceImage *sima;
int udim_source;
bContext *undo_context;
const char *undo_str;
bool use_job;
blender::geometry::UVPackIsland_Params pack_island_params;
};
static void pack_islands_startjob(void *pidv, bool *stop, bool *do_update, float *progress)
{
*progress = 0.02f;
UVPackIslandsData *pid = static_cast<UVPackIslandsData *>(pidv);
pid->pack_island_params.stop = stop;
pid->pack_island_params.do_update = do_update;
pid->pack_island_params.progress = progress;
uvedit_pack_islands_multi(pid->scene,
pid->objects,
pid->objects_len,
nullptr,
(pid->udim_source == PACK_UDIM_SRC_CLOSEST) ? pid->sima : nullptr,
(pid->udim_source == PACK_ORIGINAL_AABB),
!pid->use_job,
&pid->pack_island_params);
*progress = 0.99f;
*do_update = true;
}
static void pack_islands_endjob(void *pidv)
{
UVPackIslandsData *pid = static_cast<UVPackIslandsData *>(pidv);
for (uint ob_index = 0; ob_index < pid->objects_len; ob_index++) {
Object *obedit = pid->objects[ob_index];
DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data);
}
WM_main_add_notifier(NC_SPACE | ND_SPACE_IMAGE, NULL);
if (pid->undo_str) {
ED_undo_push(pid->undo_context, pid->undo_str);
}
}
static void pack_islands_freejob(void *pidv)
{
WM_cursor_wait(false);
UVPackIslandsData *pid = static_cast<UVPackIslandsData *>(pidv);
MEM_freeN(pid->objects);
WM_set_locked_interface(pid->wm, false);
MEM_freeN(pid);
}
static int pack_islands_exec(bContext *C, wmOperator *op)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
@ -1400,7 +1489,23 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin);
}
blender::geometry::UVPackIsland_Params pack_island_params;
UVPackIslandsData *pid = static_cast<UVPackIslandsData *>(
MEM_callocN(sizeof(UVPackIslandsData), "pack_islands_data"));
pid->use_job = op->flag & OP_IS_INVOKE;
pid->scene = scene;
pid->objects = objects;
pid->objects_len = objects_len;
pid->sima = sima;
pid->udim_source = udim_source;
pid->wm = CTX_wm_manager(C);
blender::geometry::UVPackIsland_Params &pack_island_params = pid->pack_island_params;
{
/* Call default constructor and copy the defaults. */
blender::geometry::UVPackIsland_Params default_params;
pack_island_params = default_params;
}
pack_island_params.setFromUnwrapOptions(options);
pack_island_params.rotate = RNA_boolean_get(op->ptr, "rotate");
pack_island_params.scale_to_fit = RNA_boolean_get(op->ptr, "scale");
@ -1416,15 +1521,31 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
pack_island_params.setUDIMOffsetFromSpaceImage(sima);
}
uvedit_pack_islands_multi(scene,
objects,
objects_len,
nullptr,
(udim_source == PACK_UDIM_SRC_CLOSEST) ? sima : nullptr,
(udim_source == PACK_ORIGINAL_AABB),
&pack_island_params);
if (pid->use_job) {
/* Setup job. */
if (pid->wm->op_undo_depth == 0) {
/* The job must do it's own undo push. */
pid->undo_context = C;
pid->undo_str = op->type->name;
}
MEM_freeN(objects);
wmJob *wm_job = WM_jobs_get(
pid->wm, CTX_wm_window(C), scene, "Packing UVs", WM_JOB_PROGRESS, WM_JOB_TYPE_UV_PACK);
WM_jobs_customdata_set(wm_job, pid, pack_islands_freejob);
WM_jobs_timer(wm_job, 0.1, 0, 0);
WM_set_locked_interface(pid->wm, true);
WM_jobs_callbacks(wm_job, pack_islands_startjob, nullptr, nullptr, pack_islands_endjob);
WM_cursor_wait(true);
G.is_break = false;
WM_jobs_start(CTX_wm_manager(C), wm_job);
return OPERATOR_FINISHED;
}
pack_islands_startjob(pid, nullptr, nullptr, nullptr);
pack_islands_endjob(pid);
MEM_freeN(pid);
return OPERATOR_FINISHED;
}
@ -1452,7 +1573,7 @@ static const EnumPropertyItem pack_shape_method_items[] = {
};
static const EnumPropertyItem pinned_islands_method_items[] = {
{ED_UVPACK_PIN_NORMAL, "NORMAL", 0, "Normal", "Pin information is not used"},
{ED_UVPACK_PIN_DEFAULT, "DEFAULT", 0, "Default", "Pin information is not used"},
{ED_UVPACK_PIN_IGNORED, "IGNORED", 0, "Ignored", "Pinned islands are not packed"},
{ED_UVPACK_PIN_LOCK_SCALE, "SCALE", 0, "Locked scale", "Pinned islands won't rescale"},
{ED_UVPACK_PIN_LOCK_ROTATION, "ROTATION", 0, "Locked rotation", "Pinned islands won't rotate"},
@ -1487,10 +1608,21 @@ void UV_OT_pack_islands(wmOperatorType *ot)
ot->description =
"Transform all islands so that they fill up the UV/UDIM space as much as possible";
#ifdef USE_INTERACTIVE_PACK
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
#else
/* The operator will handle undo, so the job system can push() it after the job completes. */
ot->flag = OPTYPE_REGISTER;
#endif
/* api callbacks */
ot->exec = pack_islands_exec;
#ifdef USE_INTERACTIVE_PACK
ot->invoke = WM_operator_props_popup_call;
#else
ot->invoke = WM_operator_props_popup_confirm;
#endif
ot->poll = ED_operator_uvedit;
/* properties */
@ -1510,7 +1642,7 @@ void UV_OT_pack_islands(wmOperatorType *ot)
RNA_def_enum(ot->srna,
"pin_method",
pinned_islands_method_items,
ED_UVPACK_PIN_NORMAL,
ED_UVPACK_PIN_DEFAULT,
"Pinned Islands",
"");
RNA_def_enum(ot->srna,
@ -2234,7 +2366,7 @@ void ED_uvedit_live_unwrap(const Scene *scene, Object **objects, int objects_len
pack_island_params.margin = scene->toolsettings->uvcalc_margin;
uvedit_pack_islands_multi(
scene, objects, objects_len, nullptr, nullptr, false, &pack_island_params);
scene, objects, objects_len, nullptr, nullptr, false, true, &pack_island_params);
}
}
@ -2377,7 +2509,7 @@ static int unwrap_exec(bContext *C, wmOperator *op)
pack_island_params.margin = RNA_float_get(op->ptr, "margin");
uvedit_pack_islands_multi(
scene, objects, objects_len, nullptr, nullptr, false, &pack_island_params);
scene, objects, objects_len, nullptr, nullptr, false, true, &pack_island_params);
MEM_freeN(objects);
@ -2759,7 +2891,7 @@ static int smart_project_exec(bContext *C, wmOperator *op)
params.margin = RNA_float_get(op->ptr, "island_margin");
uvedit_pack_islands_multi(
scene, objects_changed, object_changed_len, nullptr, nullptr, false, &params);
scene, objects_changed, object_changed_len, nullptr, nullptr, false, true, &params);
/* #uvedit_pack_islands_multi only supports `per_face_aspect = false`. */
const bool per_face_aspect = false;
@ -3747,7 +3879,7 @@ void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob)
params.margin_method = ED_UVPACK_MARGIN_SCALED;
params.margin = 0.001f;
uvedit_pack_islands_multi(scene, &ob, 1, &bm, nullptr, false, &params);
uvedit_pack_islands_multi(scene, &ob, 1, &bm, nullptr, false, true, &params);
/* Write back from BMesh to Mesh. */
BMeshToMeshParams bm_to_me_params{};

View File

@ -37,7 +37,7 @@ enum eUVPackIsland_ShapeMethod {
enum eUVPackIsland_PinMethod {
ED_UVPACK_PIN_IGNORED = 0,
ED_UVPACK_PIN_NORMAL,
ED_UVPACK_PIN_DEFAULT,
ED_UVPACK_PIN_LOCK_ROTATION,
ED_UVPACK_PIN_LOCK_ROTATION_SCALE,
ED_UVPACK_PIN_LOCK_SCALE,
@ -55,6 +55,7 @@ class UVPackIsland_Params {
void setFromUnwrapOptions(const UnwrapOptions &options);
void setUDIMOffsetFromSpaceImage(const SpaceImage *sima);
bool isCancelled() const;
/** Islands can be rotated to improve packing. */
bool rotate;
@ -84,6 +85,12 @@ class UVPackIsland_Params {
float target_aspect_y;
/** Which shape to use when packing. */
eUVPackIsland_ShapeMethod shape_method;
/** Abandon packing early when set by the job system. */
bool *stop;
bool *do_update;
/** How much progress we have made. From wmJob. */
float *progress;
};
class uv_phi;

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_kdtree.h"
#include "BLI_offset_indices.hh"
#include "BLI_task.hh"
#include "DNA_pointcloud_types.h"
@ -80,27 +81,25 @@ PointCloud *point_merge_by_distance(const PointCloud &src_points,
}
/* This array stores an offset into `merge_map` for every result point. */
Array<int> map_offsets(dst_size + 1);
Array<int> map_offsets_data(dst_size + 1);
int offset = 0;
for (const int i : IndexRange(dst_size)) {
map_offsets[i] = offset;
map_offsets_data[i] = offset;
offset += point_merge_counts[i];
}
map_offsets.last() = offset;
map_offsets_data.last() = offset;
OffsetIndices<int> map_offsets(map_offsets_data);
point_merge_counts.fill(0);
/* This array stores all of the source indices for every result point. The size is the source
* size because every input point is either merged with another or copied directly. */
Array<int> merge_map(src_size);
Array<int> merge_map_indices(src_size);
for (const int i : IndexRange(src_size)) {
const int merge_index = merge_indices[i];
const int dst_index = src_to_dst_indices[merge_index];
const IndexRange points(map_offsets[dst_index],
map_offsets[dst_index + 1] - map_offsets[dst_index]);
MutableSpan<int> point_merge_indices = merge_map.as_mutable_span().slice(points);
point_merge_indices[point_merge_counts[dst_index]] = i;
merge_map_indices[map_offsets[dst_index].first() + point_merge_counts[dst_index]] = i;
point_merge_counts[dst_index]++;
}
@ -114,8 +113,7 @@ PointCloud *point_merge_by_distance(const PointCloud &src_points,
threading::parallel_for(IndexRange(dst_size), 1024, [&](IndexRange range) {
for (const int i_dst : range) {
const IndexRange points(map_offsets[i_dst], map_offsets[i_dst + 1] - map_offsets[i_dst]);
dst.span[i_dst] = src[points.first()];
dst.span[i_dst] = src[map_offsets[i_dst].first()];
}
});
@ -143,9 +141,7 @@ PointCloud *point_merge_by_distance(const PointCloud &src_points,
* in the mixer the size of the result point cloud and to improve memory locality. */
bke::attribute_math::DefaultMixer<T> mixer{dst_attribute.span.slice(i_dst, 1)};
const IndexRange points(map_offsets[i_dst],
map_offsets[i_dst + 1] - map_offsets[i_dst]);
Span<int> src_merge_indices = merge_map.as_span().slice(points);
Span<int> src_merge_indices = merge_map_indices.as_span().slice(map_offsets[i_dst]);
for (const int i_src : src_merge_indices) {
mixer.mix_in(0, src[i_src]);
}

View File

@ -6,6 +6,8 @@
#include "GEO_uv_pack.hh"
#include "BKE_global.h"
#include "BLI_array.hh"
#include "BLI_bounds.hh"
#include "BLI_boxpack_2d.h"
@ -329,7 +331,7 @@ UVPackIsland_Params::UVPackIsland_Params()
only_selected_faces = false;
use_seams = false;
correct_aspect = false;
pin_method = ED_UVPACK_PIN_NORMAL;
pin_method = ED_UVPACK_PIN_DEFAULT;
pin_unselected = false;
merge_overlap = false;
margin = 0.001f;
@ -338,6 +340,9 @@ UVPackIsland_Params::UVPackIsland_Params()
udim_base_offset[1] = 0.0f;
target_aspect_y = 1.0f;
shape_method = ED_UVPACK_SHAPE_AABB;
stop = nullptr;
do_update = nullptr;
progress = nullptr;
}
/* Compact representation for AABB packers. */
@ -1200,6 +1205,13 @@ static int64_t pack_island_xatlas(const Span<UVAABBIsland *> island_indices,
while (i < island_indices.size()) {
if (params.stop && G.is_break) {
*params.stop = true;
}
if (params.isCancelled()) {
break;
}
while (traced_islands < i) {
/* Trace an island that's been solved. (Greedy.) */
const int64_t island_index = island_indices[traced_islands]->index;
@ -1308,17 +1320,26 @@ static int64_t pack_island_xatlas(const Span<UVAABBIsland *> island_indices,
else {
scan_line = std::max(0, scan_line - 25); /* `-25` must by odd. */
}
if (params.progress) {
/* We don't (yet) have a good model for how long the pack operation is going
* to take, so just update the progress a little bit. */
const float previous_progress = *params.progress;
*params.do_update = true;
const float reduction = island_indices.size() / (island_indices.size() + 0.5f);
*params.progress = 1.0f - (1.0f - previous_progress) * reduction;
}
}
if (!is_larger(*r_extent, extent, params)) {
return 0;
}
*r_extent = extent;
for (const int64_t i : phis.index_range()) {
const int64_t island_index = island_indices[i]->index;
for (int64_t j = 0; j < i; j++) {
const int64_t island_index = island_indices[j]->index;
r_phis[island_index] = phis[island_index];
}
return phis.size();
return i;
}
/**
@ -1434,7 +1455,7 @@ static float pack_islands_scale_margin(const Span<PackIsland *> islands,
alpaca_cutoff = alpaca_cutoff_fast;
}
}
const int64_t max_box_pack = std::min(alpaca_cutoff, islands.size());
int64_t max_box_pack = std::min(alpaca_cutoff, islands.size());
rctf extent = {0.0f, 1e30f, 0.0f, 1e30f};
@ -1460,13 +1481,13 @@ static float pack_islands_scale_margin(const Span<PackIsland *> islands,
switch (params.shape_method) {
case ED_UVPACK_SHAPE_CONVEX:
case ED_UVPACK_SHAPE_CONCAVE:
pack_island_xatlas(aabbs.as_span().take_front(max_box_pack),
islands,
scale,
margin,
params,
r_phis,
&extent);
max_box_pack = pack_island_xatlas(aabbs.as_span().take_front(max_box_pack),
islands,
scale,
margin,
params,
r_phis,
&extent);
break;
default:
break;

View File

@ -34,8 +34,11 @@ void VKBatch::draw(int vertex_first, int vertex_count, int instance_first, int i
if (draw_indexed) {
index_buffer->upload_data();
index_buffer->bind(context);
context.command_buffer_get().draw(
index_buffer->index_len_get(), instance_count, index_buffer->index_start_get(), vertex_first, instance_first);
context.command_buffer_get().draw(index_buffer->index_len_get(),
instance_count,
index_buffer->index_start_get(),
vertex_first,
instance_first);
}
else {
context.command_buffer_get().draw(vertex_first, vertex_count, instance_first, instance_count);

View File

@ -5,11 +5,16 @@
* \ingroup gpu
*/
#include "GPU_batch.h"
#include "vk_drawlist.hh"
namespace blender::gpu {
void VKDrawList::append(GPUBatch * /*batch*/, int /*i_first*/, int /*i_count*/) {}
void VKDrawList::append(GPUBatch *batch, int instance_first, int instance_count)
{
GPU_batch_draw_advanced(batch, 0, 0, instance_first, instance_count);
}
void VKDrawList::submit() {}

View File

@ -13,7 +13,7 @@ namespace blender::gpu {
class VKDrawList : public DrawList {
public:
void append(GPUBatch *batch, int i_first, int i_count) override;
void append(GPUBatch *batch, int instance_first, int instance_count) override;
void submit() override;
};

View File

@ -96,8 +96,6 @@ void VKVertexAttributeObject::update_bindings(const VKContext &context, VKBatch
}
is_valid = true;
BLI_assert(interface.enabled_attr_mask_ == occupied_attributes);
}
void VKVertexAttributeObject::update_bindings(VKImmediate &immediate)

View File

@ -22,7 +22,8 @@ class VKImmediate;
using AttributeMask = uint16_t;
struct VKVertexAttributeObject {
class VKVertexAttributeObject {
public:
bool is_valid = false;
VkPipelineVertexInputStateCreateInfo info = {
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, NULL};

View File

@ -35,11 +35,20 @@ void VKVertexBuffer::bind_as_ssbo(uint binding)
shader->pipeline_get().descriptor_set_get().bind_as_ssbo(*this, *location);
}
void VKVertexBuffer::bind_as_texture(uint /*binding*/) {}
void VKVertexBuffer::bind_as_texture(uint /*binding*/)
{
NOT_YET_IMPLEMENTED
}
void VKVertexBuffer::wrap_handle(uint64_t /*handle*/) {}
void VKVertexBuffer::wrap_handle(uint64_t /*handle*/)
{
NOT_YET_IMPLEMENTED
}
void VKVertexBuffer::update_sub(uint /*start*/, uint /*len*/, const void * /*data*/) {}
void VKVertexBuffer::update_sub(uint /*start*/, uint /*len*/, const void * /*data*/)
{
NOT_YET_IMPLEMENTED
}
void VKVertexBuffer::read(void *data) const
{
@ -61,7 +70,14 @@ void VKVertexBuffer::acquire_data()
data = (uchar *)MEM_mallocN(sizeof(uchar) * this->size_alloc_get(), __func__);
}
void VKVertexBuffer::resize_data() {}
void VKVertexBuffer::resize_data()
{
if (usage_ == GPU_USAGE_DEVICE_ONLY) {
return;
}
data = (uchar *)MEM_reallocN(data, sizeof(uchar) * this->size_alloc_get());
}
void VKVertexBuffer::release_data()
{
@ -90,7 +106,7 @@ void VKVertexBuffer::upload_data()
allocate();
}
if (flag &= GPU_VERTBUF_DATA_DIRTY) {
if (flag & GPU_VERTBUF_DATA_DIRTY) {
void *data_to_upload = data;
if (conversion_needed(format)) {
data_to_upload = convert();
@ -108,7 +124,10 @@ void VKVertexBuffer::upload_data()
}
}
void VKVertexBuffer::duplicate_data(VertBuf * /*dst*/) {}
void VKVertexBuffer::duplicate_data(VertBuf * /*dst*/)
{
NOT_YET_IMPLEMENTED
}
void VKVertexBuffer::allocate()
{

View File

@ -630,7 +630,7 @@ const EnumPropertyItem rna_enum_transform_orientation_items[] = {
"Align the transformation axes to the 3D cursor"},
{V3D_ORIENT_PARENT,
"PARENT",
ICON_BLANK1,
ICON_ORIENTATION_PARENT,
"Parent",
"Align the transformation axes to the object's parent space"},
// {V3D_ORIENT_CUSTOM, "CUSTOM", 0, "Custom", "Use a custom transform orientation"},

View File

@ -109,9 +109,17 @@ static void rna_Operator_enum_search_invoke(bContext *C, wmOperator *op)
WM_enum_search_invoke(C, op, NULL);
}
static bool rna_event_modal_handler_add(struct bContext *C, struct wmOperator *operator)
static bool rna_event_modal_handler_add(
struct bContext *C, ReportList *reports, struct wmOperator *operator)
{
return WM_event_add_modal_handler(C, operator) != NULL;
wmWindow *win = CTX_wm_window(C);
if (win == NULL) {
BKE_report(reports, RPT_ERROR, "No active window in context!");
return false;
}
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
return WM_event_add_modal_handler_ex(win, area, region, operator) != NULL;
}
/* XXX, need a way for python to know event types, 0x0110 is hard coded */
@ -776,7 +784,7 @@ void RNA_api_wm(StructRNA *srna)
func,
"Add a modal handler to the window manager, for the given modal operator "
"(called by invoke() with self, just before returning {'RUNNING_MODAL'})");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "operator", "Operator", "", "Operator to call");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_function_return(

View File

@ -349,6 +349,7 @@ DefNode(GeometryNode, GEO_NODE_INPUT_RADIUS, 0, "INPUT_RADIUS", InputRadius, "Ra
DefNode(GeometryNode, GEO_NODE_INPUT_SCENE_TIME, 0, "INPUT_SCENE_TIME", InputSceneTime, "Scene Time", "Retrieve the current time in the scene's animation in units of seconds or frames")
DefNode(GeometryNode, GEO_NODE_INPUT_SHADE_SMOOTH, 0, "INPUT_SHADE_SMOOTH", InputShadeSmooth, "Is Shade Smooth", "Retrieve whether each face is marked for smooth shading")
DefNode(GeometryNode, GEO_NODE_INPUT_SHORTEST_EDGE_PATHS, 0, "SHORTEST_EDGE_PATHS", InputShortestEdgePaths, "Shortest Edge Paths", "")
DefNode(GeometryNode, GEO_NODE_INPUT_SIGNED_DISTANCE, 0, "SIGNED_DISTANCE", InputSignedDistance, "Signed Distance", "Retrieve the signed distance field grid called 'distance' from a volume")
DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_CYCLIC, 0, "INPUT_SPLINE_CYCLIC",InputSplineCyclic, "Is Spline Cyclic", "Retrieve whether each spline endpoint connects to the beginning")
DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_LENGTH, 0, "SPLINE_LENGTH", SplineLength, "Spline Length", "Retrieve the total length of each spline, as a distance or as a number of points")
DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_RESOLUTION, 0, "INPUT_SPLINE_RESOLUTION", InputSplineResolution, "Spline Resolution", "Retrieve the number of evaluated points that will be generated for every control point on curves")

View File

@ -102,6 +102,7 @@ set(SRC
nodes/node_geo_input_scene_time.cc
nodes/node_geo_input_shade_smooth.cc
nodes/node_geo_input_shortest_edge_paths.cc
nodes/node_geo_input_signed_distance.cc
nodes/node_geo_input_spline_cyclic.cc
nodes/node_geo_input_spline_length.cc
nodes/node_geo_input_spline_resolution.cc

View File

@ -86,6 +86,7 @@ void register_geometry_nodes()
register_node_type_geo_input_scene_time();
register_node_type_geo_input_shade_smooth();
register_node_type_geo_input_shortest_edge_paths();
register_node_type_geo_input_signed_distance();
register_node_type_geo_input_spline_cyclic();
register_node_type_geo_input_spline_length();
register_node_type_geo_input_spline_resolution();

View File

@ -83,6 +83,7 @@ void register_node_type_geo_input_radius();
void register_node_type_geo_input_scene_time();
void register_node_type_geo_input_shade_smooth();
void register_node_type_geo_input_shortest_edge_paths();
void register_node_type_geo_input_signed_distance();
void register_node_type_geo_input_spline_cyclic();
void register_node_type_geo_input_spline_length();
void register_node_type_geo_input_spline_resolution();

View File

@ -1092,14 +1092,6 @@ static void extrude_mesh_face_regions(Mesh &mesh,
BKE_mesh_runtime_clear_cache(&mesh);
}
/* Get the range into an array of extruded corners, edges, or vertices for a particular polygon. */
static IndexRange selected_corner_range(Span<int> offsets, const int index)
{
const int offset = offsets[index];
const int next_offset = offsets[index + 1];
return IndexRange(offset, next_offset - offset);
}
static void extrude_individual_mesh_faces(
Mesh &mesh,
const Field<bool> &selection_field,
@ -1130,12 +1122,13 @@ static void extrude_individual_mesh_faces(
* parallelism later on by avoiding the need to keep track of an offset when iterating through
* all polygons. */
int extrude_corner_size = 0;
Array<int> index_offsets(poly_selection.size() + 1);
Array<int> group_per_face_data(poly_selection.size() + 1);
for (const int i_selection : poly_selection.index_range()) {
index_offsets[i_selection] = extrude_corner_size;
group_per_face_data[i_selection] = extrude_corner_size;
extrude_corner_size += orig_polys[poly_selection[i_selection]].size();
}
index_offsets.last() = extrude_corner_size;
group_per_face_data.last() = extrude_corner_size;
const OffsetIndices<int> group_per_face(group_per_face_data);
const IndexRange new_vert_range{orig_vert_size, extrude_corner_size};
/* One edge connects each selected vertex to a new vertex on the extruded polygons. */
@ -1176,7 +1169,7 @@ static void extrude_individual_mesh_faces(
Array<int> duplicate_edge_indices(extrude_corner_size);
threading::parallel_for(poly_selection.index_range(), 256, [&](const IndexRange range) {
for (const int i_selection : range) {
const IndexRange extrude_range = selected_corner_range(index_offsets, i_selection);
const IndexRange extrude_range = group_per_face[i_selection];
const IndexRange poly = polys[poly_selection[i_selection]];
MutableSpan<int> poly_verts = corner_verts.slice(poly);
@ -1253,7 +1246,7 @@ static void extrude_individual_mesh_faces(
threading::parallel_for(poly_selection.index_range(), 512, [&](const IndexRange range) {
for (const int i_selection : range) {
const IndexRange poly = polys[poly_selection[i_selection]];
const IndexRange extrude_range = selected_corner_range(index_offsets, i_selection);
const IndexRange extrude_range = group_per_face[i_selection];
/* For the extruded edges, mix the data from the two neighboring original edges of
* the extruded polygon. */
@ -1283,7 +1276,7 @@ static void extrude_individual_mesh_faces(
threading::parallel_for(poly_selection.index_range(), 1024, [&](const IndexRange range) {
for (const int i_selection : range) {
const int poly_index = poly_selection[i_selection];
const IndexRange extrude_range = selected_corner_range(index_offsets, i_selection);
const IndexRange extrude_range = group_per_face[i_selection];
new_data.slice(extrude_range).fill(data[poly_index]);
}
});
@ -1297,7 +1290,7 @@ static void extrude_individual_mesh_faces(
for (const int i_selection : range) {
const IndexRange poly = polys[poly_selection[i_selection]];
const Span<T> poly_loop_data = data.slice(poly);
const IndexRange extrude_range = selected_corner_range(index_offsets, i_selection);
const IndexRange extrude_range = group_per_face[i_selection];
for (const int i : IndexRange(poly.size())) {
const int i_next = (i == poly.size() - 1) ? 0 : i + 1;
@ -1329,7 +1322,7 @@ static void extrude_individual_mesh_faces(
/* Offset the new vertices. */
threading::parallel_for(poly_selection.index_range(), 1024, [&](const IndexRange range) {
for (const int i_selection : range) {
const IndexRange extrude_range = selected_corner_range(index_offsets, i_selection);
const IndexRange extrude_range = group_per_face[i_selection];
for (float3 &position : new_positions.slice(extrude_range)) {
position += poly_offset[poly_selection[i_selection]];
}
@ -1357,7 +1350,7 @@ static void extrude_individual_mesh_faces(
threading::parallel_for(poly_selection.index_range(), 1024, [&](const IndexRange range) {
for (const int selection_i : range) {
const int poly_i = poly_selection[selection_i];
const IndexRange extrude_range = selected_corner_range(index_offsets, selection_i);
const IndexRange extrude_range = group_per_face[selection_i];
new_poly_orig_indices.slice(extrude_range).fill(poly_orig_indices[poly_i]);
}
});

View File

@ -0,0 +1,49 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "NOD_add_node_search.hh"
#include "NOD_socket_search_link.hh"
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_input_signed_distance_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Float>(N_("Signed Distance")).field_source();
}
static void search_node_add_ops(GatherAddNodeSearchParams &params)
{
if (U.experimental.use_new_volume_nodes) {
blender::nodes::search_node_add_ops_for_basic_node(params);
}
}
static void search_link_ops(GatherLinkSearchOpParams &params)
{
if (U.experimental.use_new_volume_nodes) {
blender::nodes::search_link_ops_for_basic_node(params);
}
}
static void node_geo_exec(GeoNodeExecParams params)
{
Field<float> signed_distance_field{AttributeFieldInput::Create<float>("distance")};
params.set_output("Signed Distance", std::move(signed_distance_field));
}
} // namespace blender::nodes::node_geo_input_signed_distance_cc
void register_node_type_geo_input_signed_distance()
{
namespace file_ns = blender::nodes::node_geo_input_signed_distance_cc;
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_SIGNED_DISTANCE, "Signed Distance", NODE_CLASS_INPUT);
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.declare = file_ns::node_declare;
ntype.gather_add_node_search_ops = file_ns::search_node_add_ops;
ntype.gather_link_search_ops = file_ns::search_link_ops;
nodeRegisterType(&ntype);
}

View File

@ -8,7 +8,7 @@ namespace blender::nodes::node_shader_displacement_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Float>(N_("Height")).default_value(0.0f).min(0.0f).max(1000.0f);
b.add_input<decl::Float>(N_("Midlevel")).default_value(0.0f).min(0.0f).max(1000.0f);
b.add_input<decl::Float>(N_("Midlevel")).default_value(0.5f).min(0.0f).max(1000.0f);
b.add_input<decl::Float>(N_("Scale")).default_value(1.0f).min(0.0f).max(1000.0f);
b.add_input<decl::Vector>(N_("Normal")).hide_value();
b.add_output<decl::Vector>(N_("Displacement"));
@ -17,13 +17,6 @@ static void node_declare(NodeDeclarationBuilder &b)
static void node_shader_init_displacement(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_SPACE_OBJECT; /* space */
/* Set default value here for backwards compatibility. */
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
if (STREQ(sock->name, "Midlevel")) {
((bNodeSocketValueFloat *)sock->default_value)->value = 0.5f;
}
}
}
static int gpu_shader_displacement(GPUMaterial *mat,

View File

@ -30,7 +30,11 @@ static void sh_node_tex_brick_declare(NodeDeclarationBuilder &b)
.max(0.125f)
.default_value(0.02f)
.no_muted_links();
b.add_input<decl::Float>(N_("Mortar Smooth")).min(0.0f).max(1.0f).no_muted_links();
b.add_input<decl::Float>(N_("Mortar Smooth"))
.min(0.0f)
.max(1.0f)
.default_value(0.1f)
.no_muted_links();
b.add_input<decl::Float>(N_("Bias")).min(-1.0f).max(1.0f).no_muted_links();
b.add_input<decl::Float>(N_("Brick Width"))
.min(0.01f)
@ -78,12 +82,6 @@ static void node_shader_init_tex_brick(bNodeTree * /*ntree*/, bNode *node)
tex->squash_freq = 2;
node->storage = tex;
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
if (STREQ(sock->name, "Mortar Smooth")) {
((bNodeSocketValueFloat *)sock->default_value)->value = 0.1f;
}
}
}
static int node_shader_gpu_tex_brick(GPUMaterial *mat,

View File

@ -12,7 +12,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Color>(N_("Color")).default_value({0.5f, 0.5f, 0.5f, 1.0f});
b.add_input<decl::String>(N_("Color Attribute"));
b.add_input<decl::Float>(N_("Density")).default_value(1.0f).min(0.0f).max(1000.0f);
b.add_input<decl::String>(N_("Density Attribute"));
b.add_input<decl::String>(N_("Density Attribute")).default_value("density");
b.add_input<decl::Float>(N_("Anisotropy"))
.default_value(0.0f)
.min(-1.0f)
@ -28,24 +28,12 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PROP_FACTOR);
b.add_input<decl::Color>(N_("Blackbody Tint")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
b.add_input<decl::Float>(N_("Temperature")).default_value(1000.0f).min(0.0f).max(6500.0f);
b.add_input<decl::String>(N_("Temperature Attribute"));
b.add_input<decl::String>(N_("Temperature Attribute")).default_value("temperature");
b.add_input<decl::Float>(N_("Weight")).unavailable();
b.add_output<decl::Shader>(CTX_N_(BLT_I18NCONTEXT_ID_ID, "Volume"))
.translation_context(BLT_I18NCONTEXT_ID_ID);
}
static void node_shader_init_volume_principled(bNodeTree * /*ntree*/, bNode *node)
{
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
if (STREQ(sock->name, "Density Attribute")) {
strcpy(((bNodeSocketValueString *)sock->default_value)->value, "density");
}
else if (STREQ(sock->name, "Temperature Attribute")) {
strcpy(((bNodeSocketValueString *)sock->default_value)->value, "temperature");
}
}
}
static void attribute_post_process(GPUMaterial *mat,
const char *attribute_name,
GPUNodeLink **attribute_link)
@ -143,7 +131,6 @@ void register_node_type_sh_volume_principled()
sh_node_type_base(&ntype, SH_NODE_VOLUME_PRINCIPLED, "Principled Volume", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
ntype.initfunc = file_ns::node_shader_init_volume_principled;
ntype.gpu_fn = file_ns::node_shader_gpu_volume_principled;
nodeRegisterType(&ntype);

View File

@ -519,7 +519,15 @@ void WM_event_free_ui_handler_all(struct bContext *C,
wmUIHandlerFunc handle_fn,
wmUIHandlerRemoveFunc remove_fn);
struct wmEventHandler_Op *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op);
/**
* Add a modal handler to `win`, `area` and `region` may optionally be NULL.
*/
struct wmEventHandler_Op *WM_event_add_modal_handler_ex(struct wmWindow *win,
struct ScrArea *area,
struct ARegion *region,
wmOperator *op) ATTR_NONNULL(1, 4);
struct wmEventHandler_Op *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op)
ATTR_NONNULL(1, 2);
/**
* Modal handlers store a pointer to an area which might be freed while the handler runs.
* Use this function to NULL all handler pointers to \a old_area.
@ -1518,6 +1526,7 @@ typedef enum eWM_JobType {
WM_JOB_TYPE_SEQ_DRAG_DROP_PREVIEW,
WM_JOB_TYPE_CALCULATE_SIMULATION_NODES,
WM_JOB_TYPE_BAKE_SIMULATION_NODES,
WM_JOB_TYPE_UV_PACK,
/* add as needed, bake, seq proxy build
* if having hard coded values is a problem */
} eWM_JobType;

View File

@ -4408,11 +4408,13 @@ static void WM_event_set_handler_flag(wmEventHandler *handler, const int flag)
}
#endif
wmEventHandler_Op *WM_event_add_modal_handler(bContext *C, wmOperator *op)
wmEventHandler_Op *WM_event_add_modal_handler_ex(wmWindow *win,
ScrArea *area,
ARegion *region,
wmOperator *op)
{
wmEventHandler_Op *handler = MEM_cnew<wmEventHandler_Op>(__func__);
handler->head.type = WM_HANDLER_TYPE_OP;
wmWindow *win = CTX_wm_window(C);
/* Operator was part of macro. */
if (op->opm) {
@ -4425,8 +4427,8 @@ wmEventHandler_Op *WM_event_add_modal_handler(bContext *C, wmOperator *op)
handler->op = op;
}
handler->context.area = CTX_wm_area(C); /* Means frozen screen context for modal handlers! */
handler->context.region = CTX_wm_region(C);
handler->context.area = area; /* Means frozen screen context for modal handlers! */
handler->context.region = region;
handler->context.region_type = handler->context.region ? handler->context.region->regiontype :
-1;
@ -4439,6 +4441,14 @@ wmEventHandler_Op *WM_event_add_modal_handler(bContext *C, wmOperator *op)
return handler;
}
wmEventHandler_Op *WM_event_add_modal_handler(bContext *C, wmOperator *op)
{
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
return WM_event_add_modal_handler_ex(win, area, region, op);
}
void WM_event_modal_handler_area_replace(wmWindow *win, const ScrArea *old_area, ScrArea *new_area)
{
LISTBASE_FOREACH (wmEventHandler *, handler_base, &win->modalhandlers) {

View File

@ -1070,12 +1070,20 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
}
WM_cursor_wait(false);
{
Main *bmain = CTX_data_main(C);
/* Temporarily set the window context as this was once supported, see: #107759. */
wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
wmWindow *win = static_cast<wmWindow *>(wm->windows.first);
BLI_assert(!CTX_wm_window(C));
Main *bmain = CTX_data_main(C);
BKE_callback_exec_string(
bmain, success ? BKE_CB_EVT_LOAD_POST : BKE_CB_EVT_LOAD_POST_FAIL, filepath);
CTX_wm_window_set(C, win);
BKE_callback_exec_string(
bmain, success ? BKE_CB_EVT_LOAD_POST : BKE_CB_EVT_LOAD_POST_FAIL, filepath);
CTX_wm_window_set(C, nullptr);
BLI_assert(BKE_main_namemap_validate(bmain));
BLI_assert(BKE_main_namemap_validate(bmain));
}
return success;
}
@ -1457,10 +1465,20 @@ void wm_homefile_read_post(struct bContext *C,
wm_file_read_post(C, params_file_read_post);
if (params_file_read_post->use_data) {
BKE_callback_exec_string(CTX_data_main(C),
Main *bmain = CTX_data_main(C);
/* Temporarily set the window context as this was once supported, see: #107759. */
wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
wmWindow *win = static_cast<wmWindow *>(wm->windows.first);
BLI_assert(!CTX_wm_window(C));
CTX_wm_window_set(C, win);
BKE_callback_exec_string(bmain,
params_file_read_post->success ? BKE_CB_EVT_LOAD_POST :
BKE_CB_EVT_LOAD_POST_FAIL,
/* `filpath` (empty for home-file reading). */
"");
CTX_wm_window_set(C, nullptr);
}
if (params_file_read_post->is_alloc) {

View File

@ -886,6 +886,12 @@ elseif(WIN32)
FILES ${LIBDIR}/fftw3/lib/libfftw3-3.dll
ALL
)
if(EXISTS ${LIBDIR}/fftw3/lib/libfftw3f-3.dll)
windows_install_shared_manifest(
FILES ${LIBDIR}/fftw3/lib/libfftw3f-3.dll
ALL
)
endif()
if(MSVC_ASAN)
# The ASAN DLL's can be found in the same folder as the compiler,
# this is the easiest way to find these.