Geometry Nodes: make evaluation and logging system aware of zones #109029

Closed
Jacques Lucke wants to merge 93 commits from JacquesLucke/blender:zone-evaluation into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
57 changed files with 858 additions and 824 deletions
Showing only changes of commit 0c88ef3ae3 - Show all commits

View File

@ -398,7 +398,7 @@ def lightmap_uvpack(
# Since the boxes are sized in powers of 2, we can neatly group them into bigger squares
# this is done hierarchically, so that we may avoid running the pack function
# on many thousands of boxes, (under 1k is best) because it would get slow.
# Using an off and even dict us useful because they are packed differently
# Using an odd and even dict is useful because they are packed differently
# where w/h are the same, their packed in groups of 4
# where they are different they are packed in pairs
#

View File

@ -3592,9 +3592,6 @@ class VIEW3D_MT_face_sets_init(Menu):
props = layout.operator("sculpt.face_sets_init", text="By Sharp Edges")
props.mode = 'SHARP_EDGES'
props = layout.operator("sculpt.face_sets_init", text="By Face Maps")
props.mode = 'FACE_MAPS'
class VIEW3D_MT_random_mask(Menu):
bl_label = "Random Mask"

View File

@ -258,12 +258,9 @@ class CurvesGeometry : public ::CurvesGeometry {
MutableSpan<float2> surface_uv_coords_for_write();
/**
* Calculate the largest and smallest position values, only including control points
* (rather than evaluated points). The existing values of `min` and `max` are taken into account.
*
* \return Whether there are any points. If the curve is empty, the inputs will be unaffected.
* The largest and smallest position values of evaluated points.
*/
bool bounds_min_max(float3 &min, float3 &max) const;
std::optional<Bounds<float3>> bounds_min_max() const;
private:
/* --------------------------------------------------------------------

View File

@ -8,13 +8,12 @@
* \ingroup bke
*/
#include <atomic>
#include <iostream>
#include <mutex>
#include "BLI_bounds_types.hh"
#include "BLI_function_ref.hh"
#include "BLI_map.hh"
#include "BLI_vector_set.hh"
#include "BKE_attribute.hh"
@ -194,7 +193,7 @@ struct GeometrySet {
*/
Vector<const GeometryComponent *> get_components_for_read() const;
bool compute_boundbox_without_instances(float3 *r_min, float3 *r_max) const;
std::optional<Bounds<float3>> compute_boundbox_without_instances() const;
friend std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set);

View File

@ -265,7 +265,6 @@ void BKE_mesh_nomain_to_meshkey(struct Mesh *mesh_src, struct Mesh *mesh_dst, st
/* vertex level transformations & checks (no derived mesh) */
/* basic vertex data functions */
bool BKE_mesh_minmax(const struct Mesh *me, float r_min[3], float r_max[3]);
void BKE_mesh_transform(struct Mesh *me, const float mat[4][4], bool do_keys);
void BKE_mesh_translate(struct Mesh *me, const float offset[3], bool do_keys);
@ -512,7 +511,6 @@ bool BKE_mesh_center_median(const struct Mesh *me, float r_cent[3]);
* use when we want to ignore vertex locations that don't have connected faces.
*/
bool BKE_mesh_center_median_from_polys(const struct Mesh *me, float r_cent[3]);
bool BKE_mesh_center_bounds(const struct Mesh *me, float r_cent[3]);
bool BKE_mesh_center_of_surface(const struct Mesh *me, float r_cent[3]);
/**
* \note Mesh must be manifold with consistent face-winding,

View File

@ -151,6 +151,9 @@ struct StatesAroundFrame {
class ModifierSimulationCache {
private:
mutable std::mutex states_at_frames_mutex_;
/**
* All simulation states, sorted by frame.
*/
Vector<std::unique_ptr<ModifierSimulationStateAtFrame>> states_at_frames_;
/**
* Used for baking to deduplicate arrays when writing and writing from storage. Sharing info

View File

@ -192,6 +192,7 @@ void *BKE_curves_add(Main *bmain, const char *name)
BoundBox *BKE_curves_boundbox_get(Object *ob)
{
using namespace blender;
BLI_assert(ob->type == OB_CURVES);
const Curves *curves_id = static_cast<const Curves *>(ob->data);
@ -201,17 +202,13 @@ BoundBox *BKE_curves_boundbox_get(Object *ob)
if (ob->runtime.bb == nullptr) {
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
const blender::bke::CurvesGeometry &curves = curves_id->geometry.wrap();
float3 min(FLT_MAX);
float3 max(-FLT_MAX);
if (!curves.bounds_min_max(min, max)) {
min = float3(-1);
max = float3(1);
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
if (const std::optional<Bounds<float3>> bounds = curves.bounds_min_max()) {
BKE_boundbox_init_from_minmax(ob->runtime.bb, bounds->min, bounds->max);
}
else {
BKE_boundbox_init_from_minmax(ob->runtime.bb, float3(-1), float3(1));
}
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
}
return ob->runtime.bb;

View File

@ -1096,19 +1096,14 @@ void CurvesGeometry::transform(const float4x4 &matrix)
this->tag_positions_changed();
}
bool CurvesGeometry::bounds_min_max(float3 &min, float3 &max) const
std::optional<Bounds<float3>> CurvesGeometry::bounds_min_max() const
{
if (this->points_num() == 0) {
return false;
return std::nullopt;
}
this->runtime->bounds_cache.ensure(
[&](Bounds<float3> &r_bounds) { r_bounds = *bounds::min_max(this->evaluated_positions()); });
const Bounds<float3> &bounds = this->runtime->bounds_cache.data();
min = math::min(bounds.min, min);
max = math::max(bounds.max, max);
return true;
return this->runtime->bounds_cache.data();
}
CurvesGeometry curves_copy_point_selection(

View File

@ -33,9 +33,7 @@ TEST(curves_geometry, Empty)
{
CurvesGeometry empty(0, 0);
empty.cyclic();
float3 min;
float3 max;
EXPECT_FALSE(empty.bounds_min_max(min, max));
EXPECT_FALSE(empty.bounds_min_max());
}
TEST(curves_geometry, Move)
@ -52,9 +50,7 @@ TEST(curves_geometry, Move)
EXPECT_EQ(curves.curve_offsets, nullptr); /* NOLINT: bugprone-use-after-move */
/* Just a basic check that the new curves work okay. */
float3 min;
float3 max;
EXPECT_TRUE(other.bounds_min_max(min, max));
EXPECT_TRUE(other.bounds_min_max());
curves = std::move(other);

View File

@ -196,24 +196,30 @@ Vector<const GeometryComponent *> GeometrySet::get_components_for_read() const
return components;
}
bool GeometrySet::compute_boundbox_without_instances(float3 *r_min, float3 *r_max) const
std::optional<Bounds<float3>> GeometrySet::compute_boundbox_without_instances() const
{
using namespace blender;
bool have_minmax = false;
std::optional<Bounds<float3>> bounds;
if (const PointCloud *pointcloud = this->get_pointcloud_for_read()) {
have_minmax |= pointcloud->bounds_min_max(*r_min, *r_max);
bounds = bounds::merge(bounds, pointcloud->bounds_min_max());
}
if (const Mesh *mesh = this->get_mesh_for_read()) {
have_minmax |= BKE_mesh_wrapper_minmax(mesh, *r_min, *r_max);
Bounds<float3> mesh_bounds{float3(std::numeric_limits<float>::max()),
float3(std::numeric_limits<float>::min())};
if (BKE_mesh_wrapper_minmax(mesh, mesh_bounds.min, mesh_bounds.max)) {
bounds = bounds::merge(bounds, {mesh_bounds});
}
}
if (const Volume *volume = this->get_volume_for_read()) {
have_minmax |= BKE_volume_min_max(volume, *r_min, *r_max);
Bounds<float3> volume_bounds{float3(std::numeric_limits<float>::max()),
float3(std::numeric_limits<float>::min())};
if (BKE_volume_min_max(volume, volume_bounds.min, volume_bounds.max)) {
bounds = bounds::merge(bounds, {volume_bounds});
}
}
if (const Curves *curves_id = this->get_curves_for_read()) {
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
have_minmax |= curves.bounds_min_max(*r_min, *r_max);
bounds = bounds::merge(bounds, curves_id->geometry.wrap().bounds_min_max());
}
return have_minmax;
return bounds;
}
std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set)

View File

@ -17,6 +17,7 @@
#include "BKE_material.h"
#include "BKE_object.h"
#include "BLI_bounds.hh"
#include "BLI_map.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_memarena.h"
@ -699,25 +700,21 @@ GreasePencil *BKE_grease_pencil_new_nomain()
BoundBox *BKE_grease_pencil_boundbox_get(Object *ob)
{
using namespace blender;
BLI_assert(ob->type == OB_GREASE_PENCIL);
const GreasePencil *grease_pencil = static_cast<const GreasePencil *>(ob->data);
if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
return ob->runtime.bb;
}
if (ob->runtime.bb == nullptr) {
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
}
float3 min(FLT_MAX);
float3 max(-FLT_MAX);
if (!grease_pencil->bounds_min_max(min, max)) {
min = float3(-1);
max = float3(1);
}
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
if (const std::optional<Bounds<float3>> bounds = grease_pencil->bounds_min_max()) {
BKE_boundbox_init_from_minmax(ob->runtime.bb, bounds->min, bounds->max);
}
else {
BKE_boundbox_init_from_minmax(ob->runtime.bb, float3(-1), float3(1));
}
return ob->runtime.bb;
@ -1109,21 +1106,19 @@ void GreasePencil::foreach_editable_drawing(
foreach_drawing_ex(*this, frame, EDITABLE, function);
}
bool GreasePencil::bounds_min_max(float3 &min, float3 &max) const
std::optional<blender::Bounds<blender::float3>> GreasePencil::bounds_min_max() const
{
bool found = false;
using namespace blender;
/* FIXME: this should somehow go through the visible drawings. We don't have access to the
* scene time here, so we probably need to cache the visible drawing for each layer somehow. */
std::optional<Bounds<float3>> bounds;
for (int i = 0; i < this->drawing_array_num; i++) {
GreasePencilDrawingBase *drawing_base = this->drawing_array[i];
switch (drawing_base->type) {
case GP_DRAWING: {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
const blender::bke::CurvesGeometry &curves = drawing->geometry.wrap();
if (curves.bounds_min_max(min, max)) {
found = true;
}
const bke::CurvesGeometry &curves = drawing->geometry.wrap();
bounds = bounds::merge(bounds, curves.bounds_min_max());
break;
}
case GP_DRAWING_REFERENCE: {
@ -1133,7 +1128,7 @@ bool GreasePencil::bounds_min_max(float3 &min, float3 &max) const
}
}
return found;
return bounds;
}
blender::Span<const blender::bke::greasepencil::Layer *> GreasePencil::layers() const

View File

@ -244,32 +244,7 @@ MetaElem *BKE_mball_element_add(MetaBall *mb, const int type)
BoundBox *BKE_mball_boundbox_get(Object *ob)
{
BLI_assert(ob->type == OB_MBALL);
if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
return ob->runtime.bb;
}
if (ob->runtime.bb == nullptr) {
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
}
/* Expect that this function is only called for evaluated objects. */
const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
float min[3];
float max[3];
if (mesh_eval) {
INIT_MINMAX(min, max);
if (!BKE_mesh_minmax(mesh_eval, min, max)) {
copy_v3_fl(min, -1.0f);
copy_v3_fl(max, 1.0f);
}
}
else {
copy_v3_fl(min, 0.0f);
copy_v3_fl(max, 0.0f);
}
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
ob->runtime.bb->flag &= ~BOUNDBOX_DIRTY;
BKE_object_boundbox_calc_from_evaluated_geometry(ob);
return ob->runtime.bb;
}
@ -704,14 +679,5 @@ void BKE_mball_data_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
ob->runtime.geometry_set_eval = new GeometrySet(GeometrySet::create_with_mesh(mesh));
if (ob->runtime.bb == nullptr) {
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
}
float3 min(std::numeric_limits<float>::max());
float3 max(-std::numeric_limits<float>::max());
if (!ob->runtime.geometry_set_eval->compute_boundbox_without_instances(&min, &max)) {
min = float3(0);
max = float3(0);
}
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
BKE_object_boundbox_calc_from_evaluated_geometry(ob);
};

View File

@ -1502,21 +1502,15 @@ void BKE_mesh_looptri_get_real_edges(const blender::int2 *edges,
}
}
bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
std::optional<blender::Bounds<blender::float3>> Mesh::bounds_min_max() const
{
using namespace blender;
if (me->totvert == 0) {
return false;
if (this->totvert == 0) {
return std::nullopt;
}
me->runtime->bounds_cache.ensure(
[me](Bounds<float3> &r_bounds) { r_bounds = *bounds::min_max(me->vert_positions()); });
const Bounds<float3> &bounds = me->runtime->bounds_cache.data();
copy_v3_v3(r_min, math::min(bounds.min, float3(r_min)));
copy_v3_v3(r_max, math::max(bounds.max, float3(r_max)));
return true;
this->runtime->bounds_cache.ensure(
[&](Bounds<float3> &r_bounds) { r_bounds = *bounds::min_max(this->vert_positions()); });
return this->runtime->bounds_cache.data();
}
void Mesh::bounds_set_eager(const blender::Bounds<float3> &bounds)

View File

@ -276,18 +276,6 @@ bool BKE_mesh_center_median_from_polys(const Mesh *me, float r_cent[3])
return (me->totpoly != 0);
}
bool BKE_mesh_center_bounds(const Mesh *me, float r_cent[3])
{
float min[3], max[3];
INIT_MINMAX(min, max);
if (BKE_mesh_minmax(me, min, max)) {
mid_v3_v3v3(r_cent, min, max);
return true;
}
return false;
}
bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3])
{
float poly_area;

View File

@ -29,6 +29,7 @@
#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_math_vector.hh"
#include "BLI_task.hh"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
@ -153,12 +154,19 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
bool BKE_mesh_wrapper_minmax(const Mesh *me, float min[3], float max[3])
{
using namespace blender;
switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
return BKE_editmesh_cache_calc_minmax(me->edit_mesh, me->runtime->edit_data, min, max);
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:
return BKE_mesh_minmax(me, min, max);
case ME_WRAPPER_TYPE_SUBD: {
if (const std::optional<Bounds<float3>> bounds = me->bounds_min_max()) {
copy_v3_v3(min, math::min(bounds->min, float3(min)));
copy_v3_v3(max, math::max(bounds->max, float3(max)));
return true;
}
return false;
}
}
BLI_assert_unreachable();
return false;

View File

@ -52,6 +52,7 @@
#include "DNA_world_types.h"
#include "BLI_blenlib.h"
#include "BLI_bounds.hh"
#include "BLI_kdtree.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
@ -3847,24 +3848,19 @@ void BKE_object_boundbox_calc_from_mesh(Object *ob, const Mesh *me_eval)
bool BKE_object_boundbox_calc_from_evaluated_geometry(Object *ob)
{
float3 min(FLT_MAX);
float3 max(-FLT_MAX);
using namespace blender;
std::optional<Bounds<float3>> bounds;
if (ob->runtime.geometry_set_eval) {
if (!ob->runtime.geometry_set_eval->compute_boundbox_without_instances(&min, &max)) {
min = float3(0);
max = float3(0);
}
bounds = ob->runtime.geometry_set_eval->compute_boundbox_without_instances();
}
else if (const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob)) {
if (!BKE_mesh_wrapper_minmax(mesh_eval, min, max)) {
min = float3(0);
max = float3(0);
Bounds<float3> mesh_bounds{float3(std::numeric_limits<float>::max()),
float3(std::numeric_limits<float>::min())};
if (BKE_mesh_wrapper_minmax(mesh_eval, mesh_bounds.min, mesh_bounds.max)) {
bounds = bounds::merge(bounds, {mesh_bounds});
}
}
else if (ob->runtime.curve_cache) {
BKE_displist_minmax(&ob->runtime.curve_cache->disp, min, max);
}
else {
return false;
}
@ -3872,8 +3868,12 @@ bool BKE_object_boundbox_calc_from_evaluated_geometry(Object *ob)
if (ob->runtime.bb == nullptr) {
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
}
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
if (bounds) {
BKE_boundbox_init_from_minmax(ob->runtime.bb, bounds->min, bounds->max);
}
else {
BKE_boundbox_init_from_minmax(ob->runtime.bb, float3(0), float3(0));
}
ob->runtime.bb->flag &= ~BOUNDBOX_DIRTY;

View File

@ -263,12 +263,12 @@ void BKE_pointcloud_nomain_to_pointcloud(PointCloud *pointcloud_src, PointCloud
BKE_id_free(nullptr, pointcloud_src);
}
bool PointCloud::bounds_min_max(blender::float3 &min, blender::float3 &max) const
std::optional<blender::Bounds<blender::float3>> PointCloud::bounds_min_max() const
{
using namespace blender;
using namespace blender::bke;
if (this->totpoint == 0) {
return false;
return std::nullopt;
}
this->runtime->bounds_cache.ensure([&](Bounds<float3> &r_bounds) {
const AttributeAccessor attributes = this->attributes();
@ -281,34 +281,35 @@ bool PointCloud::bounds_min_max(blender::float3 &min, blender::float3 &max) cons
r_bounds = *bounds::min_max(positions);
}
});
const Bounds<float3> &bounds = this->runtime->bounds_cache.data();
min = math::min(bounds.min, min);
max = math::max(bounds.max, max);
return true;
return this->runtime->bounds_cache.data();
}
BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
{
using namespace blender;
BLI_assert(ob->type == OB_POINTCLOUD);
if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
return ob->runtime.bb;
}
if (ob->runtime.bb == nullptr) {
ob->runtime.bb = static_cast<BoundBox *>(MEM_callocN(sizeof(BoundBox), "pointcloud boundbox"));
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
}
float3 min, max;
INIT_MINMAX(min, max);
if (ob->runtime.geometry_set_eval != nullptr) {
ob->runtime.geometry_set_eval->compute_boundbox_without_instances(&min, &max);
std::optional<Bounds<float3>> bounds;
if (ob->runtime.geometry_set_eval) {
bounds = ob->runtime.geometry_set_eval->compute_boundbox_without_instances();
}
else {
const PointCloud *pointcloud = static_cast<PointCloud *>(ob->data);
pointcloud->bounds_min_max(min, max);
bounds = pointcloud->bounds_min_max();
}
if (bounds) {
BKE_boundbox_init_from_minmax(ob->runtime.bb, bounds->min, bounds->max);
}
else {
BKE_boundbox_init_from_minmax(ob->runtime.bb, float3(-1), float3(1));
}
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
return ob->runtime.bb;
}

View File

@ -11,6 +11,7 @@
#include "DNA_node_types.h"
#include "DNA_pointcloud_types.h"
#include "BLI_binary_search.hh"
#include "BLI_fileops.hh"
#include "BLI_hash_md5.h"
#include "BLI_path_util.h"
@ -94,15 +95,34 @@ void ModifierSimulationCache::try_discover_bake(const StringRefNull absolute_bak
}
}
static int64_t find_state_at_frame(
const Span<std::unique_ptr<ModifierSimulationStateAtFrame>> states, const SubFrame &frame)
{
const int64_t i = binary_search::find_predicate_begin(
states, [&](const auto &item) { return item->frame >= frame; });
if (i == states.size()) {
return -1;
}
return i;
}
static int64_t find_state_at_frame_exact(
const Span<std::unique_ptr<ModifierSimulationStateAtFrame>> states, const SubFrame &frame)
{
const int64_t i = find_state_at_frame(states, frame);
if (i == -1) {
return -1;
}
if (states[i]->frame != frame) {
return -1;
}
return i;
}
bool ModifierSimulationCache::has_state_at_frame(const SubFrame &frame) const
{
std::lock_guard lock(states_at_frames_mutex_);
for (const auto &item : states_at_frames_) {
if (item->frame == frame) {
return true;
}
}
return false;
return find_state_at_frame_exact(states_at_frames_, frame) != -1;
}
bool ModifierSimulationCache::has_states() const
@ -115,23 +135,26 @@ const ModifierSimulationState *ModifierSimulationCache::get_state_at_exact_frame
const SubFrame &frame) const
{
std::lock_guard lock(states_at_frames_mutex_);
for (const auto &item : states_at_frames_) {
if (item->frame == frame) {
return &item->state;
}
const int64_t i = find_state_at_frame_exact(states_at_frames_, frame);
if (i == -1) {
return nullptr;
}
return nullptr;
return &states_at_frames_[i]->state;
}
ModifierSimulationState &ModifierSimulationCache::get_state_at_frame_for_write(
const SubFrame &frame)
{
std::lock_guard lock(states_at_frames_mutex_);
for (const auto &item : states_at_frames_) {
if (item->frame == frame) {
return item->state;
}
const int64_t i = find_state_at_frame_exact(states_at_frames_, frame);
if (i != -1) {
return states_at_frames_[i]->state;
}
if (!states_at_frames_.is_empty()) {
BLI_assert(frame > states_at_frames_.last()->frame);
}
states_at_frames_.append(std::make_unique<ModifierSimulationStateAtFrame>());
states_at_frames_.last()->frame = frame;
states_at_frames_.last()->state.owner_ = this;
@ -141,23 +164,22 @@ ModifierSimulationState &ModifierSimulationCache::get_state_at_frame_for_write(
StatesAroundFrame ModifierSimulationCache::get_states_around_frame(const SubFrame &frame) const
{
std::lock_guard lock(states_at_frames_mutex_);
StatesAroundFrame states_around_frame;
for (const auto &item : states_at_frames_) {
if (item->frame < frame) {
if (states_around_frame.prev == nullptr || item->frame > states_around_frame.prev->frame) {
states_around_frame.prev = item.get();
}
}
if (item->frame == frame) {
if (states_around_frame.current == nullptr) {
states_around_frame.current = item.get();
}
}
if (item->frame > frame) {
if (states_around_frame.next == nullptr || item->frame < states_around_frame.next->frame) {
states_around_frame.next = item.get();
}
const int64_t i = find_state_at_frame(states_at_frames_, frame);
StatesAroundFrame states_around_frame{};
if (i == -1) {
if (!states_at_frames_.is_empty() && states_at_frames_.last()->frame < frame) {
states_around_frame.prev = states_at_frames_.last().get();
}
return states_around_frame;
}
if (states_at_frames_[i]->frame == frame) {
states_around_frame.current = states_at_frames_[i].get();
}
if (i > 0) {
states_around_frame.prev = states_at_frames_[i - 1].get();
}
if (i < states_at_frames_.size() - 2) {
states_around_frame.next = states_at_frames_[i + 1].get();
}
return states_around_frame;
}

View File

@ -21,7 +21,7 @@ namespace blender::bounds {
/**
* Find the smallest and largest values element-wise in the span.
*/
template<typename T> inline std::optional<Bounds<T>> min_max(Span<T> values)
template<typename T> [[nodiscard]] inline std::optional<Bounds<T>> min_max(Span<T> values)
{
if (values.is_empty()) {
return std::nullopt;
@ -48,7 +48,8 @@ template<typename T> inline std::optional<Bounds<T>> min_max(Span<T> values)
* first. The template type T is expected to have an addition operator implemented with RadiusT.
*/
template<typename T, typename RadiusT>
inline std::optional<Bounds<T>> min_max_with_radii(Span<T> values, Span<RadiusT> radii)
[[nodiscard]] inline std::optional<Bounds<T>> min_max_with_radii(Span<T> values,
Span<RadiusT> radii)
{
BLI_assert(values.size() == radii.size());
if (values.is_empty()) {
@ -72,4 +73,25 @@ inline std::optional<Bounds<T>> min_max_with_radii(Span<T> values, Span<RadiusT>
});
}
template<typename T> [[nodiscard]] inline Bounds<T> merge(const Bounds<T> &a, const Bounds<T> &b)
{
return {math::min(a.min, b.min), math::max(a.max, b.max)};
}
template<typename T>
[[nodiscard]] inline std::optional<Bounds<T>> merge(const std::optional<Bounds<T>> &a,
const std::optional<Bounds<T>> &b)
{
if (a.has_value() && b.has_value()) {
return merge(*a, *b);
}
if (a.has_value()) {
return a;
}
if (b.has_value()) {
return b;
}
return std::nullopt;
}
} // namespace blender::bounds

View File

@ -2175,7 +2175,7 @@ void uiLayoutSetPropSep(uiLayout *layout, bool is_sep);
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep);
int uiLayoutGetLocalDir(const uiLayout *layout);
int uiLayoutGetOperatorContext(uiLayout *layout);
wmOperatorCallContext uiLayoutGetOperatorContext(uiLayout *layout);
bool uiLayoutGetActive(uiLayout *layout);
bool uiLayoutGetActiveDefault(uiLayout *layout);
bool uiLayoutGetActivateInit(uiLayout *layout);
@ -2523,7 +2523,7 @@ enum uiTemplateListFlags {
UI_TEMPLATE_LIST_FLAGS_LAST
};
ENUM_OPERATORS(enum uiTemplateListFlags, UI_TEMPLATE_LIST_FLAGS_LAST);
ENUM_OPERATORS(uiTemplateListFlags, UI_TEMPLATE_LIST_FLAGS_LAST);
void uiTemplateList(uiLayout *layout,
const struct bContext *C,

View File

@ -5636,7 +5636,7 @@ uiBlock *uiLayoutGetBlock(uiLayout *layout)
return layout->root->block;
}
int uiLayoutGetOperatorContext(uiLayout *layout)
wmOperatorCallContext uiLayoutGetOperatorContext(uiLayout *layout)
{
return layout->root->opcontext;
}

View File

@ -68,6 +68,20 @@ void AbstractGridView::change_state_delayed()
BLI_assert_msg(
is_reconstructed(),
"These state changes are supposed to be delayed until reconstruction is completed");
/* Debug-only sanity check: Ensure only one item requests to be active. */
#ifndef NDEBUG
bool has_active = false;
foreach_item([&has_active](AbstractGridViewItem &item) {
if (item.should_be_active().value_or(false)) {
BLI_assert_msg(
!has_active,
"Only one view item should ever return true for its `should_be_active()` method");
has_active = true;
}
});
#endif
foreach_item([](AbstractGridViewItem &item) { item.change_state_delayed(); });
}

View File

@ -122,6 +122,20 @@ void AbstractTreeView::change_state_delayed()
BLI_assert_msg(
is_reconstructed(),
"These state changes are supposed to be delayed until reconstruction is completed");
/* Debug-only sanity check: Ensure only one item requests to be active. */
#ifndef NDEBUG
bool has_active = false;
foreach_item([&has_active](AbstractTreeViewItem &item) {
if (item.should_be_active().value_or(false)) {
BLI_assert_msg(
!has_active,
"Only one view item should ever return true for its `should_be_active()` method");
has_active = true;
}
});
#endif
foreach_item([](AbstractTreeViewItem &item) { item.change_state_delayed(); });
}

View File

@ -1444,7 +1444,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
BKE_mesh_center_of_volume(me, cent);
}
else if (around == V3D_AROUND_CENTER_BOUNDS) {
BKE_mesh_center_bounds(me, cent);
if (const std::optional<Bounds<float3>> bounds = me->bounds_min_max()) {
cent = math::midpoint(bounds->min, bounds->max);
}
}
else { /* #V3D_AROUND_CENTER_MEDIAN. */
BKE_mesh_center_median(me, cent);
@ -1696,11 +1698,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
/* done */
}
else if (around == V3D_AROUND_CENTER_BOUNDS) {
float3 min(std::numeric_limits<float>::max());
float3 max(-std::numeric_limits<float>::max());
if (curves.bounds_min_max(min, max)) {
cent = math::midpoint(min, max);
}
const Bounds<float3> bounds = *curves.bounds_min_max();
cent = math::midpoint(bounds.min, bounds.max);
}
else if (around == V3D_AROUND_CENTER_MEDIAN) {
cent = calculate_mean(curves.positions());
@ -1729,10 +1728,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
/* Done. */
}
else if (around == V3D_AROUND_CENTER_BOUNDS) {
float3 min(std::numeric_limits<float>::max());
float3 max(-std::numeric_limits<float>::max());
if (pointcloud.bounds_min_max(min, max)) {
cent = math::midpoint(min, max);
if (const std::optional<Bounds<float3>> bounds = pointcloud.bounds_min_max()) {
cent = math::midpoint(bounds->min, bounds->max);
}
}
else if (around == V3D_AROUND_CENTER_MEDIAN) {

View File

@ -620,7 +620,8 @@ static Scene *preview_prepare_scene(
/* new UI convention: draw is in pixel space already. */
/* uses UI_BTYPE_ROUNDBOX button in block to get the rect */
static bool ed_preview_draw_rect(ScrArea *area, int split, int first, rcti *rect, rcti *newrect)
static bool ed_preview_draw_rect(
Scene *scene, ScrArea *area, int split, int first, rcti *rect, rcti *newrect)
{
Render *re;
RenderView *rv;
@ -668,35 +669,21 @@ static bool ed_preview_draw_rect(ScrArea *area, int split, int first, rcti *rect
}
if (rv && rv->combined_buffer.data) {
if (abs(rres.rectx - newx) < 2 && abs(rres.recty - newy) < 2) {
newrect->xmax = max_ii(newrect->xmax, rect->xmin + rres.rectx + offx);
newrect->ymax = max_ii(newrect->ymax, rect->ymin + rres.recty);
if (rres.rectx && rres.recty) {
uchar *rect_byte = static_cast<uchar *>(
MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect"));
float fx = rect->xmin + offx;
float fy = rect->ymin;
/* material preview only needs monoscopy (view 0) */
RE_AcquiredResultGet32(re, &rres, (uint *)rect_byte, 0);
ImBuf *ibuf = IMB_allocImBuf(rres.rectx, rres.recty, 0, 0);
IMB_assign_float_buffer(ibuf, rv->combined_buffer.data, IB_DO_NOT_TAKE_OWNERSHIP);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_3D_IMAGE_COLOR);
immDrawPixelsTexTiled(&state,
fx,
fy,
rres.rectx,
rres.recty,
GPU_RGBA8,
false,
rect_byte,
1.0f,
1.0f,
nullptr);
ED_draw_imbuf(
ibuf, fx, fy, false, &scene->view_settings, &scene->display_settings, 1.0f, 1.0f);
MEM_freeN(rect_byte);
IMB_freeImBuf(ibuf);
ok = true;
}
@ -711,6 +698,7 @@ static bool ed_preview_draw_rect(ScrArea *area, int split, int first, rcti *rect
void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, rcti *rect)
{
if (idp) {
Scene *scene = CTX_data_scene(C);
wmWindowManager *wm = CTX_wm_manager(C);
ScrArea *area = CTX_wm_area(C);
ID *id = (ID *)idp;
@ -730,11 +718,11 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r
newrect.ymax = rect->ymin;
if (parent) {
ok = ed_preview_draw_rect(area, 1, 1, rect, &newrect);
ok &= ed_preview_draw_rect(area, 1, 0, rect, &newrect);
ok = ed_preview_draw_rect(scene, area, 1, 1, rect, &newrect);
ok &= ed_preview_draw_rect(scene, area, 1, 0, rect, &newrect);
}
else {
ok = ed_preview_draw_rect(area, 0, 0, rect, &newrect);
ok = ed_preview_draw_rect(scene, area, 0, 0, rect, &newrect);
}
if (ok) {

View File

@ -15,6 +15,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BLI_math_vector.hh"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@ -792,21 +793,20 @@ void PAINT_OT_sample_color(wmOperatorType *ot)
/** \name Texture Paint Toggle Operator
* \{ */
static void paint_init_pivot_mesh(Object *ob, float location[3])
static blender::float3 paint_init_pivot_mesh(Object *ob)
{
using namespace blender;
const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
if (!me_eval) {
me_eval = (const Mesh *)ob->data;
}
float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
if (!BKE_mesh_minmax(me_eval, min, max)) {
zero_v3(location);
zero_v3(max);
const std::optional<Bounds<float3>> bounds = me_eval->bounds_min_max();
if (!bounds) {
return float3(0.0f);
}
interp_v3_v3v3(location, min, max, 0.5f);
return math::midpoint(bounds->min, bounds->max);
}
static void paint_init_pivot_curves(Object *ob, float location[3])
@ -824,11 +824,11 @@ static void paint_init_pivot_grease_pencil(Object *ob, float location[3])
void paint_init_pivot(Object *ob, Scene *scene)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
float location[3];
blender::float3 location;
switch (ob->type) {
case OB_MESH:
paint_init_pivot_mesh(ob, location);
location = paint_init_pivot_mesh(ob);
break;
case OB_CURVES:
paint_init_pivot_curves(ob, location);

View File

@ -186,33 +186,6 @@ void NODE_OT_clipboard_copy(wmOperatorType *ot)
/** \name Paste
* \{ */
static void remap_pairing(bNodeTree &dst_tree, const Map<const bNode *, bNode *> &node_map)
{
/* We don't have the old tree for looking up output nodes by ID,
* so we have to build a map first to find copied output nodes in the new tree. */
Map<int32_t, bNode *> dst_output_node_map;
for (const auto &item : node_map.items()) {
if (item.key->type == GEO_NODE_SIMULATION_OUTPUT) {
dst_output_node_map.add_new(item.key->identifier, item.value);
}
}
for (bNode *dst_node : node_map.values()) {
if (dst_node->type == GEO_NODE_SIMULATION_INPUT) {
NodeGeometrySimulationInput &data = *static_cast<NodeGeometrySimulationInput *>(
dst_node->storage);
if (const bNode *output_node = dst_output_node_map.lookup_default(data.output_node_id,
nullptr)) {
data.output_node_id = output_node->identifier;
}
else {
data.output_node_id = 0;
blender::nodes::update_node_declaration_and_sockets(dst_tree, *dst_node);
}
}
}
}
static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
{
SpaceNode &snode = *CTX_wm_space_node(C);
@ -327,7 +300,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
bke::nodeDeclarationEnsure(&tree, new_node);
}
remap_pairing(tree, node_map);
remap_node_pairing(tree, node_map);
tree.ensure_topology_cache();
for (bNode *new_node : node_map.values()) {

View File

@ -1261,11 +1261,11 @@ static void node_duplicate_reparent_recursive(bNodeTree *ntree,
}
}
static void remap_pairing(bNodeTree &dst_tree, const Map<bNode *, bNode *> &node_map)
void remap_node_pairing(bNodeTree &dst_tree, const Map<const bNode *, bNode *> &node_map)
{
/* We don't have the old tree for looking up output nodes by ID,
* so we have to build a map first to find copied output nodes in the new tree. */
Map<uint32_t, bNode *> dst_output_node_map;
Map<int32_t, bNode *> dst_output_node_map;
for (const auto &item : node_map.items()) {
if (item.key->type == GEO_NODE_SIMULATION_OUTPUT) {
dst_output_node_map.add_new(item.key->identifier, item.value);
@ -1376,7 +1376,14 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
}
}
remap_pairing(*ntree, node_map);
{
/* Use temporary map that has const key, because that's what the function below expects. */
Map<const bNode *, bNode *> const_node_map;
for (const auto item : node_map.items()) {
const_node_map.add(item.key, item.value);
}
remap_node_pairing(*ntree, const_node_map);
}
/* Deselect old nodes, select the copies instead. */
for (const auto item : node_map.items()) {

View File

@ -336,6 +336,8 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode,
float node_link_dim_factor(const View2D &v2d, const bNodeLink &link);
bool node_link_is_hidden_or_dimmed(const View2D &v2d, const bNodeLink &link);
void remap_node_pairing(bNodeTree &dst_tree, const Map<const bNode *, bNode *> &node_map);
void NODE_OT_duplicate(wmOperatorType *ot);
void NODE_OT_delete(wmOperatorType *ot);
void NODE_OT_delete_reconnect(wmOperatorType *ot);

View File

@ -2413,14 +2413,13 @@ static bool lineart_geometry_check_visible(double model_view_proj[4][4],
double shift_y,
Mesh *use_mesh)
{
using namespace blender;
if (!use_mesh) {
return false;
}
float mesh_min[3], mesh_max[3];
INIT_MINMAX(mesh_min, mesh_max);
BKE_mesh_minmax(use_mesh, mesh_min, mesh_max);
const Bounds<float3> bounds = *use_mesh->bounds_min_max();
BoundBox bb;
BKE_boundbox_init_from_minmax(&bb, mesh_min, mesh_max);
BKE_boundbox_init_from_minmax(&bb, bounds.min, bounds.max);
double co[8][4];
double tmp[3];

View File

@ -198,38 +198,49 @@ void ShaderCreateInfo::validate_merge(const ShaderCreateInfo &other_info)
}
};
auto print_error_msg = [&](const Resource &res) {
std::cout << name_ << ": Validation failed : Overlapping ";
auto print_error_msg = [&](const Resource &res, Vector<Resource> &resources) {
auto print_resource_name = [&](const Resource &res) {
switch (res.bind_type) {
case Resource::BindType::UNIFORM_BUFFER:
std::cout << "Uniform Buffer " << res.uniformbuf.name;
break;
case Resource::BindType::STORAGE_BUFFER:
std::cout << "Storage Buffer " << res.storagebuf.name;
break;
case Resource::BindType::SAMPLER:
std::cout << "Sampler " << res.sampler.name;
break;
case Resource::BindType::IMAGE:
std::cout << "Image " << res.image.name;
break;
default:
std::cout << "Unknown Type";
break;
}
};
switch (res.bind_type) {
case Resource::BindType::UNIFORM_BUFFER:
std::cout << "Uniform Buffer " << res.uniformbuf.name;
break;
case Resource::BindType::STORAGE_BUFFER:
std::cout << "Storage Buffer " << res.storagebuf.name;
break;
case Resource::BindType::SAMPLER:
std::cout << "Sampler " << res.sampler.name;
break;
case Resource::BindType::IMAGE:
std::cout << "Image " << res.image.name;
break;
default:
std::cout << "Unknown Type";
break;
for (const Resource &_res : resources) {
if (&res != &_res && res.bind_type == _res.bind_type && res.slot == _res.slot) {
std::cout << name_ << ": Validation failed : Overlapping ";
print_resource_name(res);
std::cout << " and ";
print_resource_name(_res);
std::cout << " at (" << res.slot << ") while merging " << other_info.name_ << std::endl;
}
}
std::cout << " (" << res.slot << ") while merging " << other_info.name_ << std::endl;
};
for (auto &res : batch_resources_) {
if (register_resource(res) == false) {
print_error_msg(res);
print_error_msg(res, batch_resources_);
print_error_msg(res, pass_resources_);
}
}
for (auto &res : pass_resources_) {
if (register_resource(res) == false) {
print_error_msg(res);
print_error_msg(res, batch_resources_);
print_error_msg(res, pass_resources_);
}
}
}

View File

@ -67,7 +67,7 @@ void IMB_exrtile_begin_write(
*
* \param passname: Here is the raw channel name without the layer.
*/
void IMB_exr_set_channel(void *handle,
bool IMB_exr_set_channel(void *handle,
const char *layname,
const char *passname,
int xstride,

View File

@ -1095,11 +1095,10 @@ bool IMB_exr_begin_read(
return true;
}
void IMB_exr_set_channel(
bool IMB_exr_set_channel(
void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect)
{
ExrHandle *data = (ExrHandle *)handle;
ExrChannel *echan;
char name[EXR_TOT_MAXNAME + 1];
if (layname && layname[0] != '\0') {
@ -1113,16 +1112,17 @@ void IMB_exr_set_channel(
BLI_strncpy(name, passname, EXR_TOT_MAXNAME - 1);
}
echan = (ExrChannel *)BLI_findstring(&data->channels, name, offsetof(ExrChannel, name));
ExrChannel *echan = (ExrChannel *)BLI_findstring(
&data->channels, name, offsetof(ExrChannel, name));
if (echan) {
echan->xstride = xstride;
echan->ystride = ystride;
echan->rect = rect;
}
else {
printf("IMB_exr_set_channel error %s\n", name);
if (echan == nullptr) {
return false;
}
echan->xstride = xstride;
echan->ystride = ystride;
echan->rect = rect;
return true;
}
float *IMB_exr_channel_rect(void *handle,
@ -1354,9 +1354,6 @@ void IMB_exr_read_channels(void *handle)
frameBuffer.insert(echan->m->internal_name,
Slice(Imf::FLOAT, (char *)rect, xstride, ystride));
}
else {
printf("warning, channel with no rect set %s\n", echan->m->internal_name.c_str());
}
}
/* Read pixels. */

View File

@ -56,13 +56,14 @@ void IMB_exrtile_begin_write(void * /*handle*/,
{
}
void IMB_exr_set_channel(void * /*handle*/,
bool IMB_exr_set_channel(void * /*handle*/,
const char * /*layname*/,
const char * /*passname*/,
int /*xstride*/,
int /*ystride*/,
float * /*rect*/)
{
return false;
}
float *IMB_exr_channel_rect(void * /*handle*/,
const char * /*layname*/,

View File

@ -323,13 +323,12 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
}
/* Blender grows its bounds cache to cover animated meshes, so only author once. */
float bound_min[3];
float bound_max[3];
INIT_MINMAX(bound_min, bound_max);
BKE_mesh_minmax(mesh, bound_min, bound_max);
pxr::VtArray<pxr::GfVec3f> extent{pxr::GfVec3f{bound_min[0], bound_min[1], bound_min[2]},
pxr::GfVec3f{bound_max[0], bound_max[1], bound_max[2]}};
usd_mesh.CreateExtentAttr().Set(extent);
if (const std::optional<Bounds<float3>> bounds = mesh->bounds_min_max()) {
pxr::VtArray<pxr::GfVec3f> extent{
pxr::GfVec3f{bounds->min[0], bounds->min[1], bounds->min[2]},
pxr::GfVec3f{bounds->max[0], bounds->max[1], bounds->max[2]}};
usd_mesh.CreateExtentAttr().Set(extent);
}
}
static void get_vertices(const Mesh *mesh, USDMeshData &usd_mesh_data)

View File

@ -13,6 +13,7 @@
#include "DNA_listBase.h"
#ifdef __cplusplus
# include "BLI_bounds_types.hh"
# include "BLI_function_ref.hh"
# include "BLI_map.hh"
# include "BLI_math_vector_types.hh"
@ -457,7 +458,7 @@ typedef struct GreasePencil {
void foreach_editable_drawing(int frame,
blender::FunctionRef<void(int, GreasePencilDrawing &)> function);
bool bounds_min_max(blender::float3 &min, blender::float3 &max) const;
std::optional<blender::Bounds<blender::float3>> bounds_min_max() const;
/* For debugging purposes. */
void print_layer_tree();

View File

@ -17,6 +17,8 @@
/** Workaround to forward-declare C++ type in C header. */
#ifdef __cplusplus
# include <optional>
# include "BLI_bounds_types.hh"
# include "BLI_math_vector_types.hh"
# include "BLI_offset_indices.hh"
@ -302,6 +304,12 @@ typedef struct Mesh {
*/
blender::Span<int> looptri_polys() const;
/**
* Calculate the largest and smallest position values of vertices.
* \note Does not take non-mesh data (edit mesh) into account, see #BKE_mesh_wrapper_minmax,
*/
std::optional<blender::Bounds<blender::float3>> bounds_min_max() const;
/** Set cached mesh bounds to a known-correct value to avoid their lazy calculation later on. */
void bounds_set_eager(const blender::Bounds<blender::float3> &bounds);

View File

@ -12,6 +12,9 @@
#include "DNA_customdata_types.h"
#ifdef __cplusplus
# include <optional>
# include "BLI_bounds_types.hh"
# include "BLI_math_vector_types.hh"
# include "BLI_span.hh"
#endif
@ -63,7 +66,7 @@ typedef struct PointCloud {
void tag_positions_changed();
void tag_radii_changed();
bool bounds_min_max(blender::float3 &min, blender::float3 &max) const;
std::optional<blender::Bounds<blender::float3>> bounds_min_max() const;
#endif
PointCloudRuntimeHandle *runtime;

View File

@ -78,7 +78,7 @@ set(DEFSRC
rna_texture.c
rna_timeline.c
rna_tracking.c
rna_ui.c
rna_ui.cc
rna_userdef.c
rna_vfont.c
rna_volume.c
@ -119,7 +119,7 @@ set(APISRC
rna_space_api.cc
rna_text_api.c
rna_texture_api.c
rna_ui_api.c
rna_ui_api.cc
rna_vfont_api.c
rna_wm_api.c
rna_wm_gizmo_api.c

View File

@ -4598,7 +4598,7 @@ static RNAProcessItem PROCESS_ITEMS[] = {
{"rna_text.c", "rna_text_api.c", RNA_def_text},
{"rna_timeline.c", NULL, RNA_def_timeline_marker},
{"rna_sound.c", "rna_sound_api.c", RNA_def_sound},
{"rna_ui.c", "rna_ui_api.c", RNA_def_ui},
{"rna_ui.cc", "rna_ui_api.cc", RNA_def_ui},
{"rna_userdef.c", NULL, RNA_def_userdef},
{"rna_vfont.c", "rna_vfont_api.c", RNA_def_vfont},
{"rna_volume.c", NULL, RNA_def_volume},

View File

@ -30,7 +30,7 @@
#define DEF_ICON_BLANK(name)
const EnumPropertyItem rna_enum_icon_items[] = {
#include "UI_icons.h"
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
#ifdef RNA_RUNTIME
@ -104,7 +104,7 @@ static void rna_uiItemR(uiLayout *layout,
}
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, prop, translate);
flag |= (slider) ? UI_ITEM_R_SLIDER : 0;
flag |= (expand) ? UI_ITEM_R_EXPAND : 0;
@ -151,7 +151,7 @@ static void rna_uiItemR_with_popover(uiLayout *layout,
flag |= (icon_only) ? UI_ITEM_R_ICON_ONLY : 0;
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, prop, translate);
uiItemFullR_with_popover(layout, ptr, prop, -1, 0, flag, name, icon, panel_type);
}
@ -180,7 +180,7 @@ static void rna_uiItemR_with_menu(uiLayout *layout,
flag |= (icon_only) ? UI_ITEM_R_ICON_ONLY : 0;
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, prop, translate);
uiItemFullR_with_menu(layout, ptr, prop, -1, 0, flag, name, icon, menu_type);
}
@ -200,7 +200,7 @@ static void rna_uiItemMenuEnumR(uiLayout *layout,
}
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, prop, translate);
uiItemMenuEnumR_prop(layout, ptr, prop, name, icon);
}
@ -224,7 +224,7 @@ static void rna_uiItemTabsEnumR(uiLayout *layout,
}
/* Get the highlight property used to gray out some of the tabs. */
PropertyRNA *prop_highlight = NULL;
PropertyRNA *prop_highlight = nullptr;
if (!RNA_pointer_is_null(ptr_highlight)) {
prop_highlight = RNA_struct_find_property(ptr_highlight, propname_highlight);
if (!prop_highlight) {
@ -267,7 +267,7 @@ static void rna_uiItemEnumR_string(uiLayout *layout,
}
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, prop, translate);
uiItemEnumR_string_prop(layout, ptr, prop, value, name, icon);
}
@ -296,7 +296,7 @@ static void rna_uiItemPointerR(uiLayout *layout,
}
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, prop, translate);
uiItemPointerR_prop(
layout, ptr, prop, searchptr, searchprop, name, icon, results_are_suggestions);
@ -321,7 +321,7 @@ static PointerRNA rna_uiItemO(uiLayout *layout,
}
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate);
name = rna_translate_ui_text(name, text_ctxt, ot->srna, nullptr, translate);
if (icon_value && !icon) {
icon = icon_value;
@ -330,7 +330,8 @@ static PointerRNA rna_uiItemO(uiLayout *layout,
flag |= (depress) ? UI_ITEM_O_DEPRESS : 0;
PointerRNA opptr;
uiItemFullO_ptr(layout, ot, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag, &opptr);
uiItemFullO_ptr(
layout, ot, name, icon, nullptr, uiLayoutGetOperatorContext(layout), flag, &opptr);
return opptr;
}
@ -352,7 +353,7 @@ static PointerRNA rna_uiItemOMenuHold(uiLayout *layout,
}
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate);
name = rna_translate_ui_text(name, text_ctxt, ot->srna, nullptr, translate);
if (icon_value && !icon) {
icon = icon_value;
}
@ -361,7 +362,7 @@ static PointerRNA rna_uiItemOMenuHold(uiLayout *layout,
PointerRNA opptr;
uiItemFullOMenuHold_ptr(
layout, ot, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag, menu, &opptr);
layout, ot, name, icon, nullptr, uiLayoutGetOperatorContext(layout), flag, menu, &opptr);
return opptr;
}
@ -371,7 +372,7 @@ static void rna_uiItemsEnumO(uiLayout *layout,
const bool icon_only)
{
int flag = icon_only ? UI_ITEM_R_ICON_ONLY : 0;
uiItemsFullEnumO(layout, opname, propname, NULL, uiLayoutGetOperatorContext(layout), flag);
uiItemsFullEnumO(layout, opname, propname, nullptr, uiLayoutGetOperatorContext(layout), flag);
}
static PointerRNA rna_uiItemMenuEnumO(uiLayout *layout,
@ -391,7 +392,7 @@ static PointerRNA rna_uiItemMenuEnumO(uiLayout *layout,
}
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate);
name = rna_translate_ui_text(name, text_ctxt, ot->srna, nullptr, translate);
PointerRNA opptr;
uiItemMenuEnumFullO_ptr(layout, C, ot, propname, name, icon, &opptr);
@ -406,7 +407,7 @@ static void rna_uiItemL(uiLayout *layout,
int icon_value)
{
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, NULL, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, nullptr, translate);
if (icon_value && !icon) {
icon = icon_value;
@ -424,7 +425,7 @@ static void rna_uiItemM(uiLayout *layout,
int icon_value)
{
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, NULL, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, nullptr, translate);
if (icon_value && !icon) {
icon = icon_value;
@ -448,7 +449,7 @@ static void rna_uiItemPopoverPanel(uiLayout *layout,
int icon_value)
{
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, NULL, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, nullptr, translate);
if (icon_value && !icon) {
icon = icon_value;
@ -488,7 +489,7 @@ static void rna_uiTemplateID(uiLayout *layout,
}
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, prop, translate);
uiTemplateID(layout, C, ptr, propname, newop, openop, unlinkop, filter, live_icon, name);
}
@ -509,7 +510,7 @@ static void rna_uiTemplateAnyID(uiLayout *layout,
}
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, prop, translate);
/* XXX This will search property again :( */
uiTemplateAnyID(layout, ptr, propname, proptypename, name);
@ -531,7 +532,7 @@ void rna_uiTemplateList(uiLayout *layout,
const bool sort_reverse,
const bool sort_lock)
{
int flags = UI_TEMPLATE_LIST_FLAG_NONE;
uiTemplateListFlags flags = UI_TEMPLATE_LIST_FLAG_NONE;
if (sort_reverse) {
flags |= UI_TEMPLATE_LIST_SORT_REVERSE;
}
@ -636,7 +637,7 @@ static void rna_uiTemplatePathBuilder(uiLayout *layout,
}
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, prop, translate);
/* XXX This will search property again :( */
uiTemplatePathBuilder(layout, ptr, propname, root_ptr, name);
@ -646,7 +647,7 @@ static void rna_uiTemplateEventFromKeymapItem(
uiLayout *layout, wmKeyMapItem *kmi, const char *name, const char *text_ctxt, bool translate)
{
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, NULL, translate);
name = rna_translate_ui_text(name, text_ctxt, nullptr, nullptr, translate);
uiTemplateEventFromKeymapItem(layout, name, kmi, true);
}
@ -666,9 +667,8 @@ static void rna_uiTemplateAssetView(uiLayout *layout,
const char *drag_opname,
PointerRNA *r_drag_op_properties)
{
AssetFilterSettings filter_settings = {
.id_types = filter_id_types ? filter_id_types : FILTER_ID_ALL,
};
AssetFilterSettings filter_settings{};
filter_settings.id_types = filter_id_types ? filter_id_types : FILTER_ID_ALL;
uiTemplateAssetView(layout,
C,
@ -692,9 +692,9 @@ static void rna_uiTemplateAssetView(uiLayout *layout,
* that currently.
*/
static const EnumPropertyItem *rna_uiTemplateAssetView_filter_id_types_itemf(
bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
bContext * /*C*/, PointerRNA * /*ptr*/, PropertyRNA * /*prop*/, bool *r_free)
{
EnumPropertyItem *items = NULL;
EnumPropertyItem *items = nullptr;
int totitem = 0;
for (int i = 0; rna_enum_id_type_filter_items[i].identifier; i++) {
@ -720,7 +720,7 @@ static uiLayout *rna_uiLayoutRowWithHeading(
uiLayout *layout, bool align, const char *heading, const char *heading_ctxt, bool translate)
{
/* Get translated heading. */
heading = rna_translate_ui_text(heading, heading_ctxt, NULL, NULL, translate);
heading = rna_translate_ui_text(heading, heading_ctxt, nullptr, nullptr, translate);
return uiLayoutRowWithHeading(layout, align, heading);
}
@ -728,7 +728,7 @@ static uiLayout *rna_uiLayoutColumnWithHeading(
uiLayout *layout, bool align, const char *heading, const char *heading_ctxt, bool translate)
{
/* Get translated heading. */
heading = rna_translate_ui_text(heading, heading_ctxt, NULL, NULL, translate);
heading = rna_translate_ui_text(heading, heading_ctxt, nullptr, nullptr, translate);
return uiLayoutColumnWithHeading(layout, align, heading);
}
@ -742,8 +742,8 @@ static const char *rna_ui_get_enum_name(bContext *C,
const char *propname,
const char *identifier)
{
PropertyRNA *prop = NULL;
const EnumPropertyItem *items = NULL;
PropertyRNA *prop = nullptr;
const EnumPropertyItem *items = nullptr;
bool free;
const char *name = "";
@ -754,7 +754,7 @@ static const char *rna_ui_get_enum_name(bContext *C,
return name;
}
RNA_property_enum_items_gettexted(C, ptr, prop, &items, NULL, &free);
RNA_property_enum_items_gettexted(C, ptr, prop, &items, nullptr, &free);
if (items) {
const int index = RNA_enum_from_identifier(items, identifier);
@ -774,8 +774,8 @@ static const char *rna_ui_get_enum_description(bContext *C,
const char *propname,
const char *identifier)
{
PropertyRNA *prop = NULL;
const EnumPropertyItem *items = NULL;
PropertyRNA *prop = nullptr;
const EnumPropertyItem *items = nullptr;
bool free;
const char *desc = "";
@ -786,7 +786,7 @@ static const char *rna_ui_get_enum_description(bContext *C,
return desc;
}
RNA_property_enum_items_gettexted(C, ptr, prop, &items, NULL, &free);
RNA_property_enum_items_gettexted(C, ptr, prop, &items, nullptr, &free);
if (items) {
const int index = RNA_enum_from_identifier(items, identifier);
@ -806,8 +806,8 @@ static int rna_ui_get_enum_icon(bContext *C,
const char *propname,
const char *identifier)
{
PropertyRNA *prop = NULL;
const EnumPropertyItem *items = NULL;
PropertyRNA *prop = nullptr;
const EnumPropertyItem *items = nullptr;
bool free;
int icon = ICON_NONE;
@ -818,7 +818,7 @@ static int rna_ui_get_enum_icon(bContext *C,
return icon;
}
RNA_property_enum_items(C, ptr, prop, &items, NULL, &free);
RNA_property_enum_items(C, ptr, prop, &items, nullptr, &free);
if (items) {
const int index = RNA_enum_from_identifier(items, identifier);
@ -839,13 +839,13 @@ static void api_ui_item_common_heading(FunctionRNA *func)
{
RNA_def_string(func,
"heading",
NULL,
nullptr,
UI_MAX_NAME_STR,
"Heading",
"Label to insert into the layout for this sub-layout");
RNA_def_string(func,
"heading_ctxt",
NULL,
nullptr,
0,
"",
"Override automatic translation context of the given heading");
@ -857,10 +857,14 @@ static void api_ui_item_common_text(FunctionRNA *func)
{
PropertyRNA *prop;
prop = RNA_def_string(func, "text", NULL, 0, "", "Override automatic text of the item");
prop = RNA_def_string(func, "text", nullptr, 0, "", "Override automatic text of the item");
RNA_def_property_clear_flag(prop, PROP_NEVER_NULL);
prop = RNA_def_string(
func, "text_ctxt", NULL, 0, "", "Override automatic translation context of the given text");
prop = RNA_def_string(func,
"text_ctxt",
nullptr,
0,
"",
"Override automatic translation context of the given text");
RNA_def_property_clear_flag(prop, PROP_NEVER_NULL);
RNA_def_boolean(
func, "translate", true, "", "Translate the given text, when UI translation is enabled");
@ -880,8 +884,8 @@ static void api_ui_item_common(FunctionRNA *func)
static void api_ui_item_op(FunctionRNA *func)
{
PropertyRNA *parm;
parm = RNA_def_string(func, "operator", NULL, 0, "", "Identifier of the operator");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "operator", nullptr, 0, "", "Identifier of the operator");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
}
static void api_ui_item_op_common(FunctionRNA *func)
@ -896,8 +900,8 @@ static void api_ui_item_rna_common(FunctionRNA *func)
parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in data");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in data");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
}
void RNA_api_ui_layout(StructRNA *srna)
@ -910,13 +914,13 @@ void RNA_api_ui_layout(StructRNA *srna)
{'v', "VECTOR", 0, "Vector", ""},
{'c', "COLOR", 0, "Color", ""},
{'h', "HUE", 0, "Hue", ""},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem id_template_filter_items[] = {
{UI_TEMPLATE_ID_FILTER_ALL, "ALL", 0, "All", ""},
{UI_TEMPLATE_ID_FILTER_AVAILABLE, "AVAILABLE", 0, "Available", ""},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem asset_view_template_options[] = {
@ -935,7 +939,7 @@ void RNA_api_ui_layout(StructRNA *srna)
0,
"",
"Do not display buttons to choose or refresh an asset library"},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
static float node_socket_color_default[] = {0.0f, 0.0f, 0.0f, 1.0f};
@ -1031,21 +1035,21 @@ void RNA_api_ui_layout(StructRNA *srna)
/* UI name, description and icon of an enum item */
func = RNA_def_function(srna, "enum_item_name", "rna_ui_get_enum_name");
parm = RNA_def_string(func, "name", NULL, 0, "", "UI name of the enum item");
parm = RNA_def_string(func, "name", nullptr, 0, "", "UI name of the enum item");
RNA_def_function_return(func, parm);
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
api_ui_item_rna_common(func);
parm = RNA_def_string(func, "identifier", NULL, 0, "", "Identifier of the enum item");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "identifier", nullptr, 0, "", "Identifier of the enum item");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_function_ui_description(func, "Return the UI name for this enum item");
func = RNA_def_function(srna, "enum_item_description", "rna_ui_get_enum_description");
parm = RNA_def_string(func, "description", NULL, 0, "", "UI description of the enum item");
parm = RNA_def_string(func, "description", nullptr, 0, "", "UI description of the enum item");
RNA_def_function_return(func, parm);
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
api_ui_item_rna_common(func);
parm = RNA_def_string(func, "identifier", NULL, 0, "", "Identifier of the enum item");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "identifier", nullptr, 0, "", "Identifier of the enum item");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_function_ui_description(func, "Return the UI description for this enum item");
func = RNA_def_function(srna, "enum_item_icon", "rna_ui_get_enum_icon");
@ -1053,8 +1057,8 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_function_return(func, parm);
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
api_ui_item_rna_common(func);
parm = RNA_def_string(func, "identifier", NULL, 0, "", "Identifier of the enum item");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "identifier", nullptr, 0, "", "Identifier of the enum item");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_function_ui_description(func, "Return the icon for this enum item");
/* items */
@ -1111,15 +1115,15 @@ void RNA_api_ui_layout(StructRNA *srna)
api_ui_item_rna_common(func);
api_ui_item_common(func);
RNA_def_boolean(func, "icon_only", false, "", "Draw only icons in tabs, no text");
parm = RNA_def_string(func, "panel", NULL, 0, "", "Identifier of the panel");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "panel", nullptr, 0, "", "Identifier of the panel");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "prop_with_menu", "rna_uiItemR_with_menu");
api_ui_item_rna_common(func);
api_ui_item_common(func);
RNA_def_boolean(func, "icon_only", false, "", "Draw only icons in tabs, no text");
parm = RNA_def_string(func, "menu", NULL, 0, "", "Identifier of the menu");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "menu", nullptr, 0, "", "Identifier of the menu");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "prop_tabs_enum", "rna_uiItemTabsEnumR");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
@ -1128,13 +1132,13 @@ void RNA_api_ui_layout(StructRNA *srna)
func, "data_highlight", "AnyType", "", "Data from which to take highlight property");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_RNAPTR);
parm = RNA_def_string(
func, "property_highlight", NULL, 0, "", "Identifier of highlight property in data");
func, "property_highlight", nullptr, 0, "", "Identifier of highlight property in data");
RNA_def_boolean(func, "icon_only", false, "", "Draw only icons in tabs, no text");
func = RNA_def_function(srna, "prop_enum", "rna_uiItemEnumR_string");
api_ui_item_rna_common(func);
parm = RNA_def_string(func, "value", NULL, 0, "", "Enum property value");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "value", nullptr, 0, "", "Enum property value");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
api_ui_item_common(func);
func = RNA_def_function(srna, "prop_search", "rna_uiItemPointerR");
@ -1143,8 +1147,8 @@ void RNA_api_ui_layout(StructRNA *srna)
func, "search_data", "AnyType", "", "Data from which to take collection to search in");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(
func, "search_property", NULL, 0, "", "Identifier of search collection property");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func, "search_property", nullptr, 0, "", "Identifier of search collection property");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
api_ui_item_common(func);
RNA_def_boolean(
func, "results_are_suggestions", false, "", "Accept inputs that do not match any item");
@ -1172,34 +1176,34 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item");
if (is_menu_hold) {
parm = RNA_def_string(func, "menu", NULL, 0, "", "Identifier of the menu");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "menu", nullptr, 0, "", "Identifier of the menu");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
}
parm = RNA_def_pointer(
func, "properties", "OperatorProperties", "", "Operator properties to fill in");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED | PARM_RNAPTR);
RNA_def_function_return(func, parm);
RNA_def_function_ui_description(func,
"Item. Places a button into the layout to call an Operator");
}
func = RNA_def_function(srna, "operator_enum", "rna_uiItemsEnumO");
parm = RNA_def_string(func, "operator", NULL, 0, "", "Identifier of the operator");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "operator", nullptr, 0, "", "Identifier of the operator");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_boolean(func, "icon_only", false, "", "Draw only icons in buttons, no text");
func = RNA_def_function(srna, "operator_menu_enum", "rna_uiItemMenuEnumO");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
/* Can't use #api_ui_item_op_common because property must come right after. */
api_ui_item_op(func);
parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
api_ui_item_common(func);
parm = RNA_def_pointer(
func, "properties", "OperatorProperties", "", "Operator properties to fill in");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED | PARM_RNAPTR);
RNA_def_function_return(func, parm);
/* useful in C but not in python */
@ -1207,23 +1211,23 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "operator_enum_single", "uiItemEnumO_string");
api_ui_item_op_common(func);
parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "value", NULL, 0, "", "Enum property value");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_string(func, "value", nullptr, 0, "", "Enum property value");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "operator_boolean", "uiItemBooleanO");
api_ui_item_op_common(func);
parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_boolean(
func, "value", false, "", "Value of the property to call the operator with");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "operator_int", "uiItemIntO");
api_ui_item_op_common(func);
parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_int(func,
"value",
0,
@ -1233,12 +1237,12 @@ void RNA_api_ui_layout(StructRNA *srna)
"Value of the property to call the operator with",
INT_MIN,
INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "operator_float", "uiItemFloatO");
api_ui_item_op_common(func);
parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_float(func,
"value",
0,
@ -1248,15 +1252,15 @@ void RNA_api_ui_layout(StructRNA *srna)
"Value of the property to call the operator with",
-FLT_MAX,
FLT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "operator_string", "uiItemStringO");
api_ui_item_op_common(func);
parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in operator");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_string(
func, "value", NULL, 0, "", "Value of the property to call the operator with");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func, "value", nullptr, 0, "", "Value of the property to call the operator with");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
# endif
func = RNA_def_function(srna, "label", "rna_uiItemL");
@ -1266,35 +1270,35 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item");
func = RNA_def_function(srna, "menu", "rna_uiItemM");
parm = RNA_def_string(func, "menu", NULL, 0, "", "Identifier of the menu");
parm = RNA_def_string(func, "menu", nullptr, 0, "", "Identifier of the menu");
api_ui_item_common(func);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item");
func = RNA_def_function(srna, "menu_contents", "rna_uiItemM_contents");
parm = RNA_def_string(func, "menu", NULL, 0, "", "Identifier of the menu");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "menu", nullptr, 0, "", "Identifier of the menu");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "popover", "rna_uiItemPopoverPanel");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_string(func, "panel", NULL, 0, "", "Identifier of the panel");
parm = RNA_def_string(func, "panel", nullptr, 0, "", "Identifier of the panel");
api_ui_item_common(func);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item");
func = RNA_def_function(srna, "popover_group", "rna_uiItemPopoverPanelFromGroup");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_enum(func, "space_type", rna_enum_space_type_items, 0, "Space Type", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_enum(
func, "region_type", rna_enum_region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "context", NULL, 0, "", "panel type context");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "category", NULL, 0, "", "panel type category");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_string(func, "context", nullptr, 0, "", "panel type context");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_string(func, "category", nullptr, 0, "", "panel type category");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "separator", "uiItemS_ex");
RNA_def_function_ui_description(func, "Item. Inserts empty space into the layout between items");
@ -1314,10 +1318,10 @@ void RNA_api_ui_layout(StructRNA *srna)
/* context */
func = RNA_def_function(srna, "context_pointer_set", "uiLayoutSetContextPointer");
parm = RNA_def_string(func, "name", NULL, 0, "Name", "Name of entry in the context");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "name", nullptr, 0, "Name", "Name of entry in the context");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func, "data", "AnyType", "", "Pointer to put in context");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED | PARM_RNAPTR);
/* templates */
func = RNA_def_function(srna, "template_header", "uiTemplateHeader");
@ -1327,10 +1331,14 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_ID", "rna_uiTemplateID");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
api_ui_item_rna_common(func);
RNA_def_string(func, "new", NULL, 0, "", "Operator identifier to create a new ID block");
RNA_def_string(
func, "open", NULL, 0, "", "Operator identifier to open a file for creating a new ID block");
RNA_def_string(func, "unlink", NULL, 0, "", "Operator identifier to unlink the ID block");
RNA_def_string(func, "new", nullptr, 0, "", "Operator identifier to create a new ID block");
RNA_def_string(func,
"open",
nullptr,
0,
"",
"Operator identifier to open a file for creating a new ID block");
RNA_def_string(func, "unlink", nullptr, 0, "", "Operator identifier to unlink the ID block");
RNA_def_enum(func,
"filter",
id_template_filter_items,
@ -1343,10 +1351,14 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_ID_preview", "uiTemplateIDPreview");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
api_ui_item_rna_common(func);
RNA_def_string(func, "new", NULL, 0, "", "Operator identifier to create a new ID block");
RNA_def_string(
func, "open", NULL, 0, "", "Operator identifier to open a file for creating a new ID block");
RNA_def_string(func, "unlink", NULL, 0, "", "Operator identifier to unlink the ID block");
RNA_def_string(func, "new", nullptr, 0, "", "Operator identifier to create a new ID block");
RNA_def_string(func,
"open",
nullptr,
0,
"",
"Operator identifier to open a file for creating a new ID block");
RNA_def_string(func, "unlink", nullptr, 0, "", "Operator identifier to unlink the ID block");
RNA_def_int(
func, "rows", 0, 0, INT_MAX, "Number of thumbnail preview rows to display", "", 0, INT_MAX);
RNA_def_int(func,
@ -1369,22 +1381,22 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_any_ID", "rna_uiTemplateAnyID");
parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in data");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in data");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_string(func,
"type_property",
NULL,
nullptr,
0,
"",
"Identifier of property in data giving the type of the ID-blocks to use");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
api_ui_item_common_text(func);
func = RNA_def_function(srna, "template_ID_tabs", "uiTemplateIDTabs");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
api_ui_item_rna_common(func);
RNA_def_string(func, "new", NULL, 0, "", "Operator identifier to create a new ID block");
RNA_def_string(func, "menu", NULL, 0, "", "Context menu identifier");
RNA_def_string(func, "new", nullptr, 0, "", "Operator identifier to create a new ID block");
RNA_def_string(func, "menu", nullptr, 0, "", "Context menu identifier");
RNA_def_enum(func,
"filter",
id_template_filter_items,
@ -1399,13 +1411,13 @@ void RNA_api_ui_layout(StructRNA *srna)
func, "search_data", "AnyType", "", "Data from which to take collection to search in");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(
func, "search_property", NULL, 0, "", "Identifier of search collection property");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func, "search_property", nullptr, 0, "", "Identifier of search collection property");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_string(
func, "new", NULL, 0, "", "Operator identifier to create a new item for the collection");
func, "new", nullptr, 0, "", "Operator identifier to create a new item for the collection");
RNA_def_string(func,
"unlink",
NULL,
nullptr,
0,
"",
"Operator identifier to unlink or delete the active "
@ -1418,13 +1430,13 @@ void RNA_api_ui_layout(StructRNA *srna)
func, "search_data", "AnyType", "", "Data from which to take collection to search in");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(
func, "search_property", NULL, 0, "", "Identifier of search collection property");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func, "search_property", nullptr, 0, "", "Identifier of search collection property");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_string(
func, "new", NULL, 0, "", "Operator identifier to create a new item for the collection");
func, "new", nullptr, 0, "", "Operator identifier to create a new item for the collection");
RNA_def_string(func,
"unlink",
NULL,
nullptr,
0,
"",
"Operator identifier to unlink or delete the active "
@ -1444,10 +1456,10 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_path_builder", "rna_uiTemplatePathBuilder");
parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in data");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in data");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func, "root", "ID", "", "ID-block from which path is evaluated from");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED | PARM_RNAPTR);
api_ui_item_common_text(func);
func = RNA_def_function(srna, "template_modifiers", "uiTemplateModifiers");
@ -1504,14 +1516,14 @@ void RNA_api_ui_layout(StructRNA *srna)
func, "Item. A preview window for materials, textures, lights or worlds");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "id", "ID", "", "ID data-block");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_boolean(func, "show_buttons", true, "", "Show preview buttons?");
RNA_def_pointer(func, "parent", "ID", "", "ID data-block");
RNA_def_pointer(func, "slot", "TextureSlot", "", "Texture slot");
RNA_def_string(
func,
"preview_id",
NULL,
nullptr,
0,
"",
"Identifier of this preview widget, if not set the ID type will be used "
@ -1539,7 +1551,7 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_icon", "uiTemplateIcon");
RNA_def_function_ui_description(func, "Display a large icon");
parm = RNA_def_int(func, "icon_value", 0, 0, INT_MAX, "Icon to display", "", 0, INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_float(func,
"scale",
1.0f,
@ -1589,12 +1601,12 @@ void RNA_api_ui_layout(StructRNA *srna)
api_ui_item_rna_common(func);
parm = RNA_def_pointer(
func, "used_layers_data", "AnyType", "", "Data from which to take property");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(
func, "used_layers_property", NULL, 0, "", "Identifier of property in data");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func, "used_layers_property", nullptr, 0, "", "Identifier of property in data");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_int(func, "active_layer", 0, 0, INT_MAX, "Active Layer", "", 0, INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "template_color_picker", "uiTemplateColorPicker");
RNA_def_function_ui_description(func, "Item. A color wheel widget to pick colors");
@ -1618,9 +1630,9 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_image_layers", "uiTemplateImageLayers");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "image", "Image", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func, "image_user", "ImageUser", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "template_image", "uiTemplateImage");
RNA_def_function_ui_description(
@ -1679,12 +1691,13 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_list", "rna_uiTemplateList");
RNA_def_function_ui_description(func, "Item. A list widget to display data, e.g. vertexgroups.");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_string(func, "listtype_name", NULL, 0, "", "Identifier of the list type to use");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(
func, "listtype_name", nullptr, 0, "", "Identifier of the list type to use");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_string(
func,
"list_id",
NULL,
nullptr,
0,
"",
"Identifier of this list widget (mandatory when using default \"" UI_UL_DEFAULT_CLASS_NAME
@ -1693,13 +1706,13 @@ void RNA_api_ui_layout(StructRNA *srna)
"name of the class used to define the uilist (for example, if the "
"class name is \"OBJECT_UL_vgroups\", and list_id is not set by the "
"script, then bl_idname = \"OBJECT_UL_vgroups\")");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(
func, "dataptr", "AnyType", "", "Data from which to take the Collection property");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(
func, "propname", NULL, 0, "", "Identifier of the Collection property in data");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func, "propname", nullptr, 0, "", "Identifier of the Collection property in data");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func,
"active_dataptr",
"AnyType",
@ -1709,14 +1722,14 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_string(
func,
"active_propname",
NULL,
nullptr,
0,
"",
"Identifier of the integer property in active_data, index of the active item");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_string(func,
"item_dyntip_propname",
NULL,
nullptr,
0,
"",
"Identifier of a string property in items, to use as tooltip content");
@ -1773,24 +1786,24 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_node_link", "uiTemplateNodeLink");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "ntree", "NodeTree", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func, "node", "Node", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func, "socket", "NodeSocket", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "template_node_view", "uiTemplateNodeView");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "ntree", "NodeTree", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func, "node", "Node", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func, "socket", "NodeSocket", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
func = RNA_def_function(srna, "template_node_asset_menu_items", "uiTemplateNodeAssetMenuItems");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_string(func, "catalog_path", NULL, 0, "", "");
parm = RNA_def_string(func, "catalog_path", nullptr, 0, "", "");
func = RNA_def_function(srna, "template_texture_user", "uiTemplateTextureUser");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
@ -1803,10 +1816,10 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_component_menu", "uiTemplateComponentMenu");
RNA_def_function_ui_description(func, "Item. Display expanded property in a popup menu");
parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in data");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_string(func, "name", NULL, 0, "", "");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(func, "property", nullptr, 0, "", "Identifier of property in data");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_string(func, "name", nullptr, 0, "", "");
/* color management templates */
func = RNA_def_function(srna, "template_colorspace_settings", "uiTemplateColorspaceSettings");
@ -1869,7 +1882,7 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_function_ui_description(func,
"Item. A text button to set the active file browser path.");
parm = RNA_def_pointer(func, "params", "FileSelectParams", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
func = RNA_def_function(
@ -1886,12 +1899,12 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_string(func,
"list_id",
NULL,
nullptr,
0,
"",
"Identifier of this asset view. Necessary to tell apart different asset "
"views and to idenify an asset view read from a .blend");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func,
"asset_library_dataptr",
"AnyType",
@ -1899,14 +1912,14 @@ void RNA_api_ui_layout(StructRNA *srna)
"Data from which to take the active asset library property");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(
func, "asset_library_propname", NULL, 0, "", "Identifier of the asset library property");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func, "asset_library_propname", nullptr, 0, "", "Identifier of the asset library property");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(
func, "assets_dataptr", "AnyType", "", "Data from which to take the asset list property");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(
func, "assets_propname", NULL, 0, "", "Identifier of the asset list property");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func, "assets_propname", nullptr, 0, "", "Identifier of the asset list property");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_pointer(func,
"active_dataptr",
"AnyType",
@ -1916,14 +1929,15 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_string(
func,
"active_propname",
NULL,
nullptr,
0,
"",
"Identifier of the integer property in active_data, index of the active item");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_property(func, "filter_id_types", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(parm, DummyRNA_NULL_items);
RNA_def_property_enum_funcs(parm, NULL, NULL, "rna_uiTemplateAssetView_filter_id_types_itemf");
RNA_def_property_enum_funcs(
parm, nullptr, nullptr, "rna_uiTemplateAssetView_filter_id_types_itemf");
RNA_def_property_flag(parm, PROP_ENUM_FLAG);
RNA_def_enum_flag(func,
"display_options",
@ -1933,7 +1947,7 @@ void RNA_api_ui_layout(StructRNA *srna)
"Displaying options for the asset view");
RNA_def_string(func,
"activate_operator",
NULL,
nullptr,
0,
"",
"Name of a custom operator to invoke when activating an item");
@ -1943,11 +1957,11 @@ void RNA_api_ui_layout(StructRNA *srna)
"OperatorProperties",
"",
"Operator properties to fill in for the custom activate operator passed to the template");
RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_RNAPTR);
RNA_def_function_output(func, parm);
RNA_def_string(func,
"drag_operator",
NULL,
nullptr,
0,
"",
"Name of a custom operator to invoke when starting to drag an item. Never "
@ -1959,7 +1973,7 @@ void RNA_api_ui_layout(StructRNA *srna)
"OperatorProperties",
"",
"Operator properties to fill in for the custom drag operator passed to the template");
RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_RNAPTR);
RNA_def_function_output(func, parm);
func = RNA_def_function(

View File

@ -266,7 +266,7 @@ static void rna_userdef_theme_update_icons(Main *bmain, Scene *scene, PointerRNA
}
/* also used by buffer swap switching */
static void rna_userdef_dpi_update(Main *UNUSED(bmain),
static void rna_userdef_gpu_update(Main *UNUSED(bmain),
Scene *UNUSED(scene),
PointerRNA *UNUSED(ptr))
{
@ -1191,7 +1191,7 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
RNA_def_property_range(prop, 6.0f, 32.0f);
RNA_def_property_ui_range(prop, 8.0f, 20.0f, 10.0f, 1);
RNA_def_property_ui_text(prop, "Points", "Font size in points");
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
RNA_def_property_update(prop, 0, "rna_userdef_gpu_update");
prop = RNA_def_property(srna, "shadow", PROP_INT, PROP_PIXEL);
RNA_def_property_range(prop, 0, 5);
@ -4642,7 +4642,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
prop, "UI Scale", "Changes the size of the fonts and widgets in the interface");
RNA_def_property_range(prop, 0.25f, 4.0f);
RNA_def_property_ui_range(prop, 0.5f, 2.0f, 1, 2);
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
RNA_def_property_update(prop, 0, "rna_userdef_gpu_update");
prop = RNA_def_property(srna, "ui_line_width", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, line_width);
@ -4650,7 +4650,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
prop,
"UI Line Width",
"Changes the thickness of widget outlines, lines and dots in the interface");
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
RNA_def_property_update(prop, 0, "rna_userdef_gpu_update");
/* display */
prop = RNA_def_property(srna, "show_tooltips", PROP_BOOLEAN, PROP_NONE);
@ -5652,7 +5652,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "gpu_flag", USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE);
RNA_def_property_ui_text(
prop, "Overlay Smooth Wires", "Enable overlay smooth wires, reducing aliasing");
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
RNA_def_property_update(prop, 0, "rna_userdef_gpu_update");
prop = RNA_def_property(srna, "use_edit_mode_smooth_wire", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(
@ -5661,13 +5661,13 @@ static void rna_def_userdef_system(BlenderRNA *brna)
prop,
"Edit Mode Smooth Wires",
"Enable edit mode edge smoothing, reducing aliasing (requires restart)");
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
RNA_def_property_update(prop, 0, "rna_userdef_gpu_update");
prop = RNA_def_property(srna, "use_region_overlap", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_REGION_OVERLAP);
RNA_def_property_ui_text(
prop, "Region Overlap", "Display tool/property regions over the main region");
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
RNA_def_property_update(prop, 0, "rna_userdef_gpu_update");
prop = RNA_def_property(srna, "viewport_aa", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_userdef_viewport_aa_items);

View File

@ -378,6 +378,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
const ModifierEvalContext *ctx,
Mesh *mesh)
{
using namespace blender;
if (mesh->totvert == 0) {
return mesh;
}
@ -458,12 +459,9 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
}
if (amd->offset_type & MOD_ARR_OFF_RELATIVE) {
float min[3], max[3];
INIT_MINMAX(min, max);
BKE_mesh_minmax(mesh, min, max);
const Bounds<float3> bounds = *mesh->bounds_min_max();
for (j = 3; j--;) {
offset[3][j] += amd->scale[j] * (max[j] - min[j]);
offset[3][j] += amd->scale[j] * (bounds.max[j] - bounds.min[j]);
}
}

View File

@ -6,6 +6,8 @@
* \ingroup modifiers
*/
#define DNA_DEPRECATED_ALLOW
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
@ -298,7 +300,7 @@ static void compute_interpolated_polys(const Mesh *mesh,
int last_corner_vert = corner_verts[start];
bool v_loop_in_mask_last = vertex_mask[last_corner_vert];
for (const int j : poly_verts_src.index_range()) {
const int corner_vert = corner_verts[(start + 1 + j) % poly_src.size()];
const int corner_vert = poly_verts_src[(start + 1 + j) % poly_src.size()];
const bool v_loop_in_mask = vertex_mask[corner_vert];
if (v_loop_in_mask && !v_loop_in_mask_last) {
dst_totloop = 3;
@ -514,9 +516,10 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
/* Ring search starting at a vertex which is not included in the mask. */
int start = -sub_poly_index - 1;
bool skip = false;
Span<int> corner_verts_src(&src_corner_verts[i_ml_src], src_poly.size());
for (const int j : corner_verts_src.index_range()) {
if (!vertex_mask[corner_verts_src[j]]) {
const Span<int> poly_verts_src = src_corner_verts.slice(src_poly);
const Span<int> poly_edges_src = src_corner_edges.slice(src_poly);
for (const int j : poly_verts_src.index_range()) {
if (!vertex_mask[poly_verts_src[j]]) {
if (start == -1) {
start = j;
break;
@ -534,47 +537,39 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
BLI_assert(start >= 0);
BLI_assert(edge_index < dst_mesh.totedge);
int last_corner_i = start;
bool v_loop_in_mask_last = vertex_mask[src_corner_verts[last_corner_i]];
int last_index = start;
for (const int j : corner_verts_src.index_range()) {
bool v_loop_in_mask_last = vertex_mask[poly_verts_src[last_index]];
for (const int j : poly_verts_src.index_range()) {
const int index = (start + 1 + j) % src_poly.size();
const bool v_loop_in_mask = vertex_mask[src_corner_verts[index]];
const bool v_loop_in_mask = vertex_mask[poly_verts_src[index]];
if (v_loop_in_mask && !v_loop_in_mask_last) {
/* Start new cut. */
float fac = get_interp_factor_from_vgroup(dvert,
defgrp_index,
threshold,
src_corner_verts[last_corner_i],
src_corner_verts[index]);
float fac = get_interp_factor_from_vgroup(
dvert, defgrp_index, threshold, poly_verts_src[last_index], poly_verts_src[index]);
float weights[2] = {1.0f - fac, fac};
int indices[2] = {i_ml_src + last_index, i_ml_src + index};
CustomData_interp(
&src_mesh.ldata, &dst_mesh.ldata, indices, weights, nullptr, 2, i_ml_dst);
dst_corner_edges[i_ml_dst] = edge_map[src_corner_edges[last_corner_i]];
dst_corner_edges[i_ml_dst] = edge_map[poly_edges_src[last_index]];
dst_corner_verts[i_ml_dst] = dst_edges[dst_corner_edges[i_ml_dst]][0];
i_ml_dst++;
CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src + index, i_ml_dst, 1);
dst_corner_verts[i_ml_dst] = vertex_map[src_corner_verts[index]];
dst_corner_edges[i_ml_dst] = edge_map[src_corner_edges[index]];
dst_corner_verts[i_ml_dst] = vertex_map[poly_verts_src[index]];
dst_corner_edges[i_ml_dst] = edge_map[poly_edges_src[index]];
i_ml_dst++;
}
else if (!v_loop_in_mask && v_loop_in_mask_last) {
BLI_assert(i_ml_dst != dst_poly_offsets[i_dst]);
/* End active cut. */
float fac = get_interp_factor_from_vgroup(dvert,
defgrp_index,
threshold,
src_corner_verts[last_corner_i],
src_corner_verts[index]);
float fac = get_interp_factor_from_vgroup(
dvert, defgrp_index, threshold, poly_verts_src[last_index], poly_verts_src[index]);
float weights[2] = {1.0f - fac, fac};
int indices[2] = {i_ml_src + last_index, i_ml_src + index};
CustomData_interp(
&src_mesh.ldata, &dst_mesh.ldata, indices, weights, nullptr, 2, i_ml_dst);
dst_corner_edges[i_ml_dst] = edge_index;
dst_corner_verts[i_ml_dst] = dst_edges[edge_map[src_corner_edges[last_corner_i]]][0];
i_ml_dst++;
dst_corner_verts[i_ml_dst] = dst_edges[edge_map[poly_edges_src[last_index]]][0];
/* Create closing edge. */
int2 &cut_edge = dst_edges[edge_index];
@ -582,6 +577,7 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
cut_edge[1] = dst_corner_verts[i_ml_dst];
BLI_assert(cut_edge[0] != cut_edge[1]);
edge_index++;
i_ml_dst++;
/* Only handle one of the cuts per iteration. */
break;
@ -590,11 +586,10 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
BLI_assert(i_ml_dst != dst_poly_offsets[i_dst]);
/* Extend active poly. */
CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src + index, i_ml_dst, 1);
dst_corner_verts[i_ml_dst] = vertex_map[src_corner_verts[index]];
dst_corner_edges[i_ml_dst] = edge_map[src_corner_edges[index]];
dst_corner_verts[i_ml_dst] = vertex_map[poly_verts_src[index]];
dst_corner_edges[i_ml_dst] = edge_map[poly_edges_src[index]];
i_ml_dst++;
}
last_corner_i = index;
last_index = index;
v_loop_in_mask_last = v_loop_in_mask;
}

View File

@ -151,18 +151,17 @@ static bool can_use_mesh_for_orco_evaluation(MeshSeqCacheModifierData *mcmd,
static Mesh *generate_bounding_box_mesh(const Mesh *org_mesh)
{
using namespace blender;
float3 min(std::numeric_limits<float>::max());
float3 max(-std::numeric_limits<float>::max());
if (!BKE_mesh_minmax(org_mesh, min, max)) {
const std::optional<Bounds<float3>> bounds = org_mesh->bounds_min_max();
if (!bounds) {
return nullptr;
}
Mesh *result = geometry::create_cuboid_mesh(max - min, 2, 2, 2);
Mesh *result = geometry::create_cuboid_mesh(bounds->max - bounds->min, 2, 2, 2);
if (org_mesh->mat) {
result->mat = static_cast<Material **>(MEM_dupallocN(org_mesh->mat));
result->totcol = org_mesh->totcol;
}
BKE_mesh_translate(result, math::midpoint(min, max), false);
BKE_mesh_translate(result, math::midpoint(bounds->min, bounds->max), false);
return result;
}

View File

@ -306,11 +306,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
psys_sim_data_init(&sim);
if (psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) {
float min[3], max[3];
INIT_MINMAX(min, max);
BKE_mesh_minmax(mesh, min, max);
min_co = min[track];
max_co = max[track];
if (const std::optional<blender::Bounds<blender::float3>> bounds = mesh->bounds_min_max()) {
min_co = bounds->min[track];
max_co = bounds->max[track];
}
}
result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, maxpoly, maxloop);

View File

@ -71,8 +71,9 @@ static void init_dualcon_mesh(DualConInput *input, Mesh *mesh)
input->tri_stride = sizeof(MLoopTri);
input->tottri = BKE_mesh_runtime_looptri_len(mesh);
INIT_MINMAX(input->min, input->max);
BKE_mesh_minmax(mesh, input->min, input->max);
const blender::Bounds<blender::float3> bounds = *mesh->bounds_min_max();
copy_v3_v3(input->min, bounds.min);
copy_v3_v3(input->max, bounds.max);
}
/* simple structure to hold the output: a CDDM and two counters to

View File

@ -879,7 +879,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
else {
origindex[mpoly_index] = ORIGINDEX_NONE;
dst_material_index[mpoly_index] = mat_nr;
sharp_faces.span[i] = use_flat_shading;
sharp_faces.span[mpoly_index] = use_flat_shading;
}
poly_offests_new[mpoly_index] = mpoly_index * 4;

View File

@ -22,16 +22,14 @@ static void node_geo_exec(GeoNodeExecParams params)
/* Compute the min and max of all realized geometry for the two
* vector outputs, which are only meant to consider real geometry. */
float3 min = float3(FLT_MAX);
float3 max = float3(-FLT_MAX);
geometry_set.compute_boundbox_without_instances(&min, &max);
if (min == float3(FLT_MAX)) {
const std::optional<Bounds<float3>> bounds = geometry_set.compute_boundbox_without_instances();
if (!bounds) {
params.set_output("Min", float3(0));
params.set_output("Max", float3(0));
}
else {
params.set_output("Min", min);
params.set_output("Max", max);
params.set_output("Min", bounds->min);
params.set_output("Max", bounds->max);
}
/* Generate the bounding box meshes inside each unique geometry set (including individually for
@ -39,24 +37,22 @@ static void node_geo_exec(GeoNodeExecParams params)
* repurpose the original geometry sets for the output. */
if (params.output_is_required("Bounding Box")) {
geometry_set.modify_geometry_sets([&](GeometrySet &sub_geometry) {
float3 sub_min = float3(FLT_MAX);
float3 sub_max = float3(-FLT_MAX);
std::optional<Bounds<float3>> sub_bounds;
/* Reuse the min and max calculation if this is the main "real" geometry set. */
if (&sub_geometry == &geometry_set) {
sub_min = min;
sub_max = max;
sub_bounds = bounds;
}
else {
sub_geometry.compute_boundbox_without_instances(&sub_min, &sub_max);
sub_bounds = sub_geometry.compute_boundbox_without_instances();
}
if (sub_min == float3(FLT_MAX)) {
if (!sub_bounds) {
sub_geometry.remove_geometry_during_modify();
}
else {
const float3 scale = sub_max - sub_min;
const float3 center = sub_min + scale / 2.0f;
const float3 scale = sub_bounds->max - sub_bounds->min;
const float3 center = sub_bounds->min + scale / 2.0f;
Mesh *mesh = geometry::create_cuboid_mesh(scale, 2, 2, 2, "uv_map");
transform_mesh(*mesh, center, float3(0), float3(1));
sub_geometry.replace_mesh(mesh);

View File

@ -264,15 +264,6 @@ struct RenderStats *RE_GetStats(struct Render *re);
* Caller is responsible for allocating `rect` in correct size!
*/
void RE_ResultGet32(struct Render *re, unsigned int *rect);
/**
* Only for acquired results, for lock.
*
* \note The caller is responsible for allocating `rect` in correct size!
*/
void RE_AcquiredResultGet32(struct Render *re,
struct RenderResult *result,
unsigned int *rect,
int view_id);
void RE_render_result_full_channel_name(char *fullname,
const char *layname,

View File

@ -362,6 +362,7 @@ struct MultiresBakeThread {
MultiresBakeRender *bkr;
Image *image;
void *bake_data;
int num_total_faces;
/* thread-specific data */
MBakeRast bake_rast;
@ -437,7 +438,7 @@ static void *do_multires_bake_thread(void *data_v)
if (bkr->progress) {
*bkr->progress = (float(bkr->baked_objects) +
float(bkr->baked_faces) / handle->queue->tot_tri) /
float(bkr->baked_faces) / handle->num_total_faces) /
bkr->tot_obj;
}
BLI_spin_unlock(&handle->queue->spin);
@ -566,6 +567,7 @@ static void do_multires_bake(MultiresBakeRender *bkr,
handle->bkr = bkr;
handle->image = ima;
handle->num_total_faces = queue.tot_tri * BLI_listbase_count(&ima->tiles);
handle->queue = &queue;
handle->data.vert_positions = positions;

View File

@ -507,17 +507,6 @@ void RE_ResultGet32(Render *re, uint *rect)
RE_ReleaseResultImageViews(re, &rres);
}
void RE_AcquiredResultGet32(Render *re, RenderResult *result, uint *rect, const int view_id)
{
render_result_rect_get_pixels(result,
rect,
re->rectx,
re->recty,
&re->scene->view_settings,
&re->scene->display_settings,
view_id);
}
RenderStats *RE_GetStats(Render *re)
{
return &re->i;
@ -2524,6 +2513,11 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode)
void RE_layer_load_from_file(
RenderLayer *layer, ReportList *reports, const char *filepath, int x, int y)
{
/* First try loading multilayer EXR. */
if (render_result_exr_file_read_path(nullptr, layer, reports, filepath)) {
return;
}
/* OCIO_TODO: assume layer was saved in default color space */
ImBuf *ibuf = IMB_loadiffname(filepath, IB_rect, nullptr);
RenderPass *rpass = nullptr;
@ -2593,7 +2587,7 @@ void RE_layer_load_from_file(
void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filepath)
{
if (!render_result_exr_file_read_path(result, nullptr, filepath)) {
if (!render_result_exr_file_read_path(result, nullptr, reports, filepath)) {
BKE_reportf(reports, RPT_ERROR, "%s: failed to load '%s'", __func__, filepath);
return;
}

View File

@ -824,31 +824,35 @@ void render_result_single_layer_end(Render *re)
re->pushedresult = nullptr;
}
int render_result_exr_file_read_path(RenderResult *rr,
RenderLayer *rl_single,
const char *filepath)
bool render_result_exr_file_read_path(RenderResult *rr,
RenderLayer *rl_single,
ReportList *reports,
const char *filepath)
{
void *exrhandle = IMB_exr_get_handle();
int rectx, recty;
if (!IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty, false)) {
printf("failed being read %s\n", filepath);
IMB_exr_close(exrhandle);
return 0;
return false;
}
if (rr == nullptr || rectx != rr->rectx || recty != rr->recty) {
if (rr) {
printf("error in reading render result: dimensions don't match\n");
}
else {
printf("error in reading render result: nullptr result pointer\n");
}
ListBase layers = (rr) ? rr->layers : ListBase{rl_single, rl_single};
const int expected_rectx = (rr) ? rr->rectx : rl_single->rectx;
const int expected_recty = (rr) ? rr->recty : rl_single->recty;
bool found_channels = false;
if (rectx != expected_rectx || recty != expected_recty) {
BKE_reportf(reports,
RPT_ERROR,
"reading render result: dimensions don't match, expected %dx%d",
expected_rectx,
expected_recty);
IMB_exr_close(exrhandle);
return 0;
return true;
}
LISTBASE_FOREACH (RenderLayer *, rl, &rr->layers) {
LISTBASE_FOREACH (RenderLayer *, rl, &layers) {
if (rl_single && rl_single != rl) {
continue;
}
@ -856,14 +860,39 @@ int render_result_exr_file_read_path(RenderResult *rr,
/* passes are allocated in sync */
LISTBASE_FOREACH (RenderPass *, rpass, &rl->passes) {
const int xstride = rpass->channels;
const int ystride = xstride * rectx;
int a;
char fullname[EXR_PASS_MAXNAME];
for (a = 0; a < xstride; a++) {
RE_render_result_full_channel_name(
fullname, nullptr, rpass->name, rpass->view, rpass->chan_id, a);
IMB_exr_set_channel(
exrhandle, rl->name, fullname, xstride, xstride * rectx, rpass->buffer.data + a);
if (IMB_exr_set_channel(
exrhandle, rl->name, fullname, xstride, ystride, rpass->buffer.data + a)) {
found_channels = true;
}
else if (rl_single) {
if (IMB_exr_set_channel(
exrhandle, nullptr, fullname, xstride, ystride, rpass->buffer.data + a)) {
found_channels = true;
}
else {
BKE_reportf(nullptr,
RPT_WARNING,
"reading render result: expected channel \"%s.%s\" or \"%s\" not found",
rl->name,
fullname,
fullname);
}
}
else {
BKE_reportf(nullptr,
RPT_WARNING,
"reading render result: expected channel \"%s.%s\" not found",
rl->name,
fullname);
}
}
RE_render_result_full_channel_name(
@ -871,10 +900,13 @@ int render_result_exr_file_read_path(RenderResult *rr,
}
}
IMB_exr_read_channels(exrhandle);
if (found_channels) {
IMB_exr_read_channels(exrhandle);
}
IMB_exr_close(exrhandle);
return 1;
return true;
}
#define FILE_CACHE_MAX (FILE_MAXFILE + FILE_MAXFILE + MAX_ID_NAME + 100)

View File

@ -21,6 +21,7 @@ struct Render;
struct RenderData;
struct RenderLayer;
struct RenderResult;
struct ReportList;
struct rcti;
#ifdef __cplusplus
@ -95,9 +96,10 @@ struct RenderPass *render_layer_add_pass(struct RenderResult *rr,
/**
* Called for reading temp files, and for external engines.
*/
int render_result_exr_file_read_path(struct RenderResult *rr,
struct RenderLayer *rl_single,
const char *filepath);
bool render_result_exr_file_read_path(struct RenderResult *rr,
struct RenderLayer *rl_single,
struct ReportList *reports,
const char *filepath);
/* EXR cache */

View File

@ -195,7 +195,7 @@ typedef enum eWM_CursorWrapAxis {
/**
* Context to call operator in for #WM_operator_name_call.
* rna_ui.c contains EnumPropertyItem's of these, keep in sync.
* rna_ui.cc contains EnumPropertyItem's of these, keep in sync.
*/
typedef enum wmOperatorCallContext {
/* if there's invoke, call it, otherwise exec */

View File

@ -768,7 +768,7 @@ class GeoNodesSimulationTest(MeshTest):
raise Exception("The object has no modifiers.")
scene = bpy.context.scene
for frame in range(1, self.frames_num+1):
for frame in range(1, self.frames_num + 1):
scene.frame_set(frame)
for modifier in modifiers_list: