WIP: Vulkan: Workbench #107886
|
@ -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(
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 |
Binary file not shown.
Binary file not shown.
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
/** \} */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -508,6 +508,7 @@ set(ICON_NAMES
|
|||
ipo_ease_out
|
||||
ipo_ease_in_out
|
||||
normalize_fcurves
|
||||
orientation_parent
|
||||
vertexsel
|
||||
edgesel
|
||||
facesel
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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, ¶ms);
|
||||
scene, objects_changed, object_changed_len, nullptr, nullptr, false, true, ¶ms);
|
||||
|
||||
/* #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, ¶ms);
|
||||
uvedit_pack_islands_multi(scene, &ob, 1, &bm, nullptr, false, true, ¶ms);
|
||||
|
||||
/* Write back from BMesh to Mesh. */
|
||||
BMeshToMeshParams bm_to_me_params{};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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 ¶ms)
|
||||
{
|
||||
if (U.experimental.use_new_volume_nodes) {
|
||||
blender::nodes::search_node_add_ops_for_basic_node(params);
|
||||
}
|
||||
}
|
||||
|
||||
static void search_link_ops(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
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);
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue