UI: Asset Shelf (Experimental Feature) #104831

Closed
Julian Eisel wants to merge 399 commits from asset-shelf into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
210 changed files with 1513 additions and 1121 deletions
Showing only changes of commit 60be0a43ec - Show all commits

View File

@ -49,7 +49,7 @@ if(MSVC)
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/lib/fftw3f.lib ${HARVEST_TARGET}/fftw3/lib/fftw3f.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/bin/fftw3f.dll ${HARVEST_TARGET}/fftw3/lib/fftw3f.dll
DEPENDEES install
)
)
endif()
endif()

View File

@ -7,7 +7,6 @@ set(GMP_EXTRA_ARGS -enable-cxx)
if(WIN32)
cmake_to_msys_path("${BUILD_DIR}/gmp/src/external_gmp/compile" compilescript_path)
set(arlib_joint_path "ar-lib lib.exe")
set(GMP_CFLAGS "-nologo -W3 -utf-8 -MP -MD -Z7 -Ob0 -Od -Xcompiler -RTC1 -DWIN32 -D_WINDOWS")
set(GMP_CC_CXX "${compilescript_path} cl")

View File

@ -15,7 +15,7 @@ if(NOT WIN32)
INSTALL_DIR ${LIBDIR}/ogg
)
else()
ExternalProject_Add(external_ogg
ExternalProject_Add(external_ogg
URL file://${PACKAGE_DIR}/${OGG_FILE}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH ${OGG_HASH_TYPE}=${OGG_HASH}

View File

@ -95,7 +95,7 @@ set(USD_EXTRA_ARGS
)
# Ray: I'm not sure if the other platforms relied on this or not but this is no longer
# needed for windows. If mac/lin confirm, this can be removed.
# needed for windows. If mac/lin confirm, this can be removed.
if(NOT WIN32)
list(APPEND USD_EXTRA_ARGS
# USD wants the tbb debug lib set even when you are doing a release build

View File

@ -12,8 +12,8 @@
# LAME_FOUND - True if Lame found.
if (LAME_INCLUDE_DIR)
# Already in cache, be silent
set(LAME_FIND_QUIETLY TRUE)
# Already in cache, be silent
set(LAME_FIND_QUIETLY TRUE)
endif ()
find_path (LAME_INCLUDE_DIR lame/lame.h

View File

@ -23,7 +23,7 @@ if(LLVM_ROOT_DIR)
endif()
else()
if(DEFINED LLVM_VERSION)
message(running llvm-config-${LLVM_VERSION})
message(running llvm-config-${LLVM_VERSION})
find_program(LLVM_CONFIG llvm-config-${LLVM_VERSION})
endif()
if(NOT LLVM_CONFIG)

View File

@ -279,18 +279,18 @@ function(gtest_add_tests)
endif()
set(options
SKIP_DEPENDENCY
SKIP_DEPENDENCY
)
set(oneValueArgs
TARGET
WORKING_DIRECTORY
TEST_PREFIX
TEST_SUFFIX
TEST_LIST
TARGET
WORKING_DIRECTORY
TEST_PREFIX
TEST_SUFFIX
TEST_LIST
)
set(multiValueArgs
SOURCES
EXTRA_ARGS
SOURCES
EXTRA_ARGS
)
set(allKeywords ${options} ${oneValueArgs} ${multiValueArgs})

View File

@ -928,6 +928,27 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
unset(MOLD_BIN)
endif()
if(WITH_LINKER_LLD AND _IS_LINKER_DEFAULT)
find_program(LLD_BIN "ld.lld")
mark_as_advanced(LLD_BIN)
if(NOT LLD_BIN)
message(STATUS "The \"ld.lld\" binary could not be found, using system linker.")
set(WITH_LINKER_LLD OFF)
else()
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0)
string(APPEND CMAKE_EXE_LINKER_FLAGS " --ld-path=\"${LLD_BIN}\"")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " --ld-path=\"${LLD_BIN}\"")
string(APPEND CMAKE_MODULE_LINKER_FLAGS " --ld-path=\"${LLD_BIN}\"")
else()
string(APPEND CMAKE_EXE_LINKER_FLAGS " -fuse-ld=\"${LLD_BIN}\"")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -fuse-ld=\"${LLD_BIN}\"")
string(APPEND CMAKE_MODULE_LINKER_FLAGS " -fuse-ld=\"${LLD_BIN}\"")
endif()
set(_IS_LINKER_DEFAULT OFF)
endif()
unset(LLD_BIN)
endif()
# Intel C++ Compiler
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
# think these next two are broken

View File

@ -29,6 +29,8 @@ set(SRC
src/config_hurd.h
src/config_linux.h
src/config_mac.h
src/config_netbsd.h
src/config_openbsd.h
src/base/commandlineflags.h
src/base/googleinit.h

View File

@ -13,7 +13,7 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
endif()
if(WIN32)
add_definitions(-D_USE_MATH_DEFINES)
add_definitions(-D_USE_MATH_DEFINES)
endif()
set(LEMON_3RD_PATH 3rd/lemon-1.3.1)

View File

@ -20,6 +20,16 @@
CCL_NAMESPACE_BEGIN
ccl_device_forceinline bool integrator_intersect_skip_lights(KernelGlobals kg,
IntegratorState state)
{
/* When direct lighting is disabled for baking, we skip light sampling in
* integrate_surface_direct_light for the first bounce. Therefore, in order
* for MIS to be consistent, we also need to skip evaluating lights here. */
return (kernel_data.integrator.filter_closures & FILTER_CLOSURE_DIRECT_LIGHT) &&
(INTEGRATOR_STATE(state, path, bounce) == 1);
}
ccl_device_forceinline bool integrator_intersect_terminate(KernelGlobals kg,
IntegratorState state,
const int shader_flags)
@ -262,7 +272,12 @@ ccl_device_forceinline void integrator_intersect_next_kernel(
}
else {
/* Nothing hit, continue with background kernel. */
integrator_path_next(kg, state, current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
if (integrator_intersect_skip_lights(kg, state)) {
integrator_path_terminate(kg, state, current_kernel);
}
else {
integrator_path_next(kg, state, current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
}
}
}
@ -314,8 +329,12 @@ ccl_device_forceinline void integrator_intersect_next_kernel_after_volume(
}
else {
/* Nothing hit, continue with background kernel. */
integrator_path_next(kg, state, current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
return;
if (integrator_intersect_skip_lights(kg, state)) {
integrator_path_terminate(kg, state, current_kernel);
}
else {
integrator_path_next(kg, state, current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
}
}
}
@ -389,7 +408,7 @@ ccl_device void integrator_intersect_closest(KernelGlobals kg,
#endif /* __MNEE__ */
/* Light intersection for MIS. */
if (kernel_data.integrator.use_light_mis) {
if (kernel_data.integrator.use_light_mis && !integrator_intersect_skip_lights(kg, state)) {
/* NOTE: if we make lights visible to camera rays, we'll need to initialize
* these in the path_state_init. */
const int last_type = INTEGRATOR_STATE(state, isect, type);

View File

@ -43,7 +43,7 @@ set(SRC
)
set(LIB
bf_blenkernel
bf_blenkernel
)

View File

@ -7,6 +7,15 @@
* \ingroup bke
*/
#ifdef __cplusplus
namespace blender::bke {
struct GeometrySet;
}
using GeometrySetHandle = blender::bke::GeometrySet;
#else
typedef struct GeometrySetHandle GeometrySetHandle;
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -19,7 +28,6 @@ struct ParticleSystem;
struct Scene;
struct ViewLayer;
struct ViewerPath;
struct GeometrySet;
/* ---------------------------------------------------- */
/* Dupli-Geometry */
@ -51,7 +59,7 @@ typedef struct DupliObject {
short type; /* from Object.transflag */
char no_draw;
/* If this dupli object is belongs to a preview, this is non-null. */
const struct GeometrySet *preview_base_geometry;
const GeometrySetHandle *preview_base_geometry;
/* Index of the top-level instance this dupli is part of or -1 when unused. */
int preview_instance_index;
@ -71,7 +79,7 @@ typedef struct DupliObject {
* size between 1 and MAX_DUPLI_RECUR can be used without issues.
*/
int instance_idx[4];
const struct GeometrySet *instance_data[4];
const GeometrySetHandle *instance_data[4];
/* Random ID for shading */
unsigned int random_id;

View File

@ -97,21 +97,21 @@ class GeometryFieldContext : public fn::FieldContext {
* instead of #Curves.
*/
const void *geometry_;
const GeometryComponentType type_;
const GeometryComponent::Type type_;
const eAttrDomain domain_;
friend GeometryFieldInput;
public:
GeometryFieldContext(const GeometryComponent &component, eAttrDomain domain);
GeometryFieldContext(const void *geometry, GeometryComponentType type, eAttrDomain domain);
GeometryFieldContext(const void *geometry, GeometryComponent::Type type, eAttrDomain domain);
const void *geometry() const
{
return geometry_;
}
GeometryComponentType type() const
GeometryComponent::Type type() const
{
return type_;
}

View File

@ -1,38 +0,0 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup bke
*/
#ifdef __cplusplus
extern "C" {
#endif
struct GeometrySet;
struct Object;
/* Each geometry component has a specific type. The type determines what kind of data the component
* stores. Functions modifying a geometry will usually just modify a subset of the component types.
*/
typedef enum GeometryComponentType {
GEO_COMPONENT_TYPE_MESH = 0,
GEO_COMPONENT_TYPE_POINT_CLOUD = 1,
GEO_COMPONENT_TYPE_INSTANCES = 2,
GEO_COMPONENT_TYPE_VOLUME = 3,
GEO_COMPONENT_TYPE_CURVE = 4,
GEO_COMPONENT_TYPE_EDIT = 5,
} GeometryComponentType;
#define GEO_COMPONENT_TYPE_ENUM_SIZE 6
void BKE_geometry_set_free(struct GeometrySet *geometry_set);
bool BKE_object_has_geometry_set_instances(const struct Object *ob);
#ifdef __cplusplus
}
#endif

View File

@ -17,7 +17,6 @@
#include "BLI_vector_set.hh"
#include "BKE_attribute.hh"
#include "BKE_geometry_set.h"
struct Curves;
struct Curve;
@ -25,6 +24,10 @@ struct Mesh;
struct PointCloud;
struct Volume;
namespace blender::bke {
#define GEO_COMPONENT_TYPE_ENUM_SIZE 6
enum class GeometryOwnershipType {
/* The geometry is owned. This implies that it can be changed. */
Owned = 0,
@ -34,28 +37,42 @@ enum class GeometryOwnershipType {
ReadOnly = 2,
};
namespace blender::bke {
class ComponentAttributeProviders;
class CurvesEditHints;
class Instances;
} // namespace blender::bke
class GeometryComponent;
using GeometryComponentPtr = blender::ImplicitSharingPtr<GeometryComponent>;
using GeometryComponentPtr = ImplicitSharingPtr<GeometryComponent>;
/**
* This is the base class for specialized geometry component types. A geometry component uses
* implicit sharing to avoid read-only copies. It also integrates with attribute API, which
* generalizes storing and modifying generic information on a geometry.
*/
class GeometryComponent : public blender::ImplicitSharingMixin {
class GeometryComponent : public ImplicitSharingMixin {
public:
/**
* Each geometry component has a specific type. The type determines what kind of data the
* component stores. Functions modifying a geometry will usually just modify a subset of the
* component types.
* \note These values are stored in files, so they should not be reordered.
*/
enum class Type {
Mesh = 0,
PointCloud = 1,
Instance = 2,
Volume = 3,
Curve = 4,
Edit = 5,
};
private:
GeometryComponentType type_;
Type type_;
public:
GeometryComponent(GeometryComponentType type);
GeometryComponent(Type type);
virtual ~GeometryComponent() = default;
static GeometryComponentPtr create(GeometryComponentType component_type);
static GeometryComponentPtr create(Type component_type);
int attribute_domain_size(eAttrDomain domain) const;
@ -63,8 +80,8 @@ class GeometryComponent : public blender::ImplicitSharingMixin {
* Get access to the attributes in this geometry component. May return none if the geometry does
* not support the attribute system.
*/
virtual std::optional<blender::bke::AttributeAccessor> attributes() const;
virtual std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write();
virtual std::optional<AttributeAccessor> attributes() const;
virtual std::optional<MutableAttributeAccessor> attributes_for_write();
/* The returned component should be of the same type as the type this is called on. */
virtual GeometryComponent *copy() const = 0;
@ -78,7 +95,7 @@ class GeometryComponent : public blender::ImplicitSharingMixin {
virtual bool owns_direct_data() const = 0;
virtual void ensure_owns_direct_data() = 0;
GeometryComponentType type() const;
Type type() const;
virtual bool is_empty() const;
@ -110,7 +127,7 @@ inline constexpr bool is_geometry_component_v = std::is_base_of_v<GeometryCompon
*/
struct GeometrySet {
private:
/* Indexed by #GeometryComponentType. */
/* Indexed by #GeometryComponent::Type. */
std::array<GeometryComponentPtr, GEO_COMPONENT_TYPE_ENUM_SIZE> components_;
public:
@ -128,7 +145,7 @@ struct GeometrySet {
* This method can only be used when the geometry set is mutable. It returns a mutable geometry
* component of the given type.
*/
GeometryComponent &get_component_for_write(GeometryComponentType component_type);
GeometryComponent &get_component_for_write(GeometryComponent::Type component_type);
template<typename Component> Component &get_component_for_write()
{
BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
@ -138,21 +155,21 @@ struct GeometrySet {
/**
* Get the component of the given type. Might return null if the component does not exist yet.
*/
const GeometryComponent *get_component_for_read(GeometryComponentType component_type) const;
const GeometryComponent *get_component_for_read(GeometryComponent::Type component_type) const;
template<typename Component> const Component *get_component_for_read() const
{
BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
return static_cast<const Component *>(get_component_for_read(Component::static_type));
}
bool has(const GeometryComponentType component_type) const;
bool has(const GeometryComponent::Type component_type) const;
template<typename Component> bool has() const
{
BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
return this->has(Component::static_type);
}
void remove(const GeometryComponentType component_type);
void remove(const GeometryComponent::Type component_type);
template<typename Component> void remove()
{
BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
@ -162,12 +179,12 @@ struct GeometrySet {
/**
* Remove all geometry components with types that are not in the provided list.
*/
void keep_only(const blender::Span<GeometryComponentType> component_types);
void keep_only(const Span<GeometryComponent::Type> component_types);
/**
* Keeps the provided geometry types, but also instances and edit data.
* Instances must not be removed while using #modify_geometry_sets.
*/
void keep_only_during_modify(const blender::Span<GeometryComponentType> component_types);
void keep_only_during_modify(const Span<GeometryComponent::Type> component_types);
void remove_geometry_during_modify();
void add(const GeometryComponent &component);
@ -175,9 +192,9 @@ struct GeometrySet {
/**
* Get all geometry components in this geometry set for read-only access.
*/
blender::Vector<const GeometryComponent *> get_components_for_read() const;
Vector<const GeometryComponent *> get_components_for_read() const;
bool compute_boundbox_without_instances(blender::float3 *r_min, blender::float3 *r_max) const;
bool compute_boundbox_without_instances(float3 *r_min, float3 *r_max) const;
friend std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set);
@ -199,26 +216,24 @@ struct GeometrySet {
*/
void ensure_owns_all_data();
using AttributeForeachCallback =
blender::FunctionRef<void(const blender::bke::AttributeIDRef &attribute_id,
const blender::bke::AttributeMetaData &meta_data,
const GeometryComponent &component)>;
using AttributeForeachCallback = FunctionRef<void(const AttributeIDRef &attribute_id,
const AttributeMetaData &meta_data,
const GeometryComponent &component)>;
void attribute_foreach(blender::Span<GeometryComponentType> component_types,
void attribute_foreach(Span<GeometryComponent::Type> component_types,
bool include_instances,
AttributeForeachCallback callback) const;
void gather_attributes_for_propagation(
blender::Span<GeometryComponentType> component_types,
GeometryComponentType dst_component_type,
bool include_instances,
const blender::bke::AnonymousAttributePropagationInfo &propagation_info,
blender::Map<blender::bke::AttributeIDRef, blender::bke::AttributeKind> &r_attributes) const;
void gather_attributes_for_propagation(Span<GeometryComponent::Type> component_types,
GeometryComponent::Type dst_component_type,
bool include_instances,
const AnonymousAttributePropagationInfo &propagation_info,
Map<AttributeIDRef, AttributeKind> &r_attributes) const;
blender::Vector<GeometryComponentType> gather_component_types(bool include_instances,
bool ignore_empty) const;
Vector<GeometryComponent::Type> gather_component_types(bool include_instances,
bool ignore_empty) const;
using ForeachSubGeometryCallback = blender::FunctionRef<void(GeometrySet &geometry_set)>;
using ForeachSubGeometryCallback = FunctionRef<void(GeometrySet &geometry_set)>;
/**
* Modify every (recursive) instance separately. This is often more efficient than realizing all
@ -251,8 +266,7 @@ struct GeometrySet {
* Create a new geometry set that only contains the given instances.
*/
static GeometrySet create_with_instances(
blender::bke::Instances *instances,
GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
Instances *instances, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
/* Utility methods for access. */
/**
@ -303,11 +317,11 @@ struct GeometrySet {
/**
* Returns read-only instances or null.
*/
const blender::bke::Instances *get_instances_for_read() const;
const Instances *get_instances_for_read() const;
/**
* Returns read-only curve edit hints or null.
*/
const blender::bke::CurvesEditHints *get_curve_edit_hints_for_read() const;
const CurvesEditHints *get_curve_edit_hints_for_read() const;
/**
* Returns a mutable mesh or null. No ownership is transferred.
@ -328,11 +342,11 @@ struct GeometrySet {
/**
* Returns mutable instances or null. No ownership is transferred.
*/
blender::bke::Instances *get_instances_for_write();
Instances *get_instances_for_write();
/**
* Returns mutable curve edit hints or null.
*/
blender::bke::CurvesEditHints *get_curve_edit_hints_for_write();
CurvesEditHints *get_curve_edit_hints_for_write();
/* Utility methods for replacement. */
/**
@ -357,7 +371,7 @@ struct GeometrySet {
/**
* Clear the existing instances and replace them with the given one.
*/
void replace_instances(blender::bke::Instances *instances,
void replace_instances(Instances *instances,
GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
private:
@ -365,7 +379,7 @@ struct GeometrySet {
* Retrieve the pointer to a component without creating it if it does not exist,
* unlike #get_component_for_write.
*/
GeometryComponent *get_component_ptr(GeometryComponentType type);
GeometryComponent *get_component_ptr(GeometryComponent::Type type);
template<typename Component> Component *get_component_ptr()
{
BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
@ -418,10 +432,10 @@ class MeshComponent : public GeometryComponent {
bool owns_direct_data() const override;
void ensure_owns_direct_data() override;
static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_MESH;
static constexpr inline GeometryComponent::Type static_type = Type::Mesh;
std::optional<blender::bke::AttributeAccessor> attributes() const final;
std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
std::optional<AttributeAccessor> attributes() const final;
std::optional<MutableAttributeAccessor> attributes_for_write() final;
};
/**
@ -475,12 +489,10 @@ class PointCloudComponent : public GeometryComponent {
bool owns_direct_data() const override;
void ensure_owns_direct_data() override;
std::optional<blender::bke::AttributeAccessor> attributes() const final;
std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
std::optional<AttributeAccessor> attributes() const final;
std::optional<MutableAttributeAccessor> attributes_for_write() final;
static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_POINT_CLOUD;
private:
static constexpr inline GeometryComponent::Type static_type = Type::PointCloud;
};
/**
@ -528,10 +540,10 @@ class CurveComponent : public GeometryComponent {
*/
const Curve *get_curve_for_render() const;
std::optional<blender::bke::AttributeAccessor> attributes() const final;
std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
std::optional<AttributeAccessor> attributes() const final;
std::optional<MutableAttributeAccessor> attributes_for_write() final;
static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_CURVE;
static constexpr inline GeometryComponent::Type static_type = Type::Curve;
};
/**
@ -539,7 +551,7 @@ class CurveComponent : public GeometryComponent {
*/
class InstancesComponent : public GeometryComponent {
private:
blender::bke::Instances *instances_ = nullptr;
Instances *instances_ = nullptr;
GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
public:
@ -549,10 +561,10 @@ class InstancesComponent : public GeometryComponent {
void clear() override;
const blender::bke::Instances *get_for_read() const;
blender::bke::Instances *get_for_write();
const Instances *get_for_read() const;
Instances *get_for_write();
void replace(blender::bke::Instances *instances,
void replace(Instances *instances,
GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
bool is_empty() const final;
@ -560,10 +572,10 @@ class InstancesComponent : public GeometryComponent {
bool owns_direct_data() const override;
void ensure_owns_direct_data() override;
std::optional<blender::bke::AttributeAccessor> attributes() const final;
std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
std::optional<AttributeAccessor> attributes() const final;
std::optional<MutableAttributeAccessor> attributes_for_write() final;
static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_INSTANCES;
static constexpr inline GeometryComponent::Type static_type = Type::Instance;
};
/**
@ -608,7 +620,7 @@ class VolumeComponent : public GeometryComponent {
bool owns_direct_data() const override;
void ensure_owns_direct_data() override;
static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_VOLUME;
static constexpr inline GeometryComponent::Type static_type = Type::Volume;
};
/**
@ -626,7 +638,7 @@ class GeometryComponentEditData final : public GeometryComponent {
* because the data remains valid even when there is no actual curves geometry anymore, for
* example, when the curves have been converted to a mesh.
*/
std::unique_ptr<blender::bke::CurvesEditHints> curves_edit_hints_;
std::unique_ptr<CurvesEditHints> curves_edit_hints_;
GeometryComponentEditData();
@ -644,5 +656,7 @@ class GeometryComponentEditData final : public GeometryComponent {
*/
static void remember_deformed_curve_positions_if_necessary(GeometrySet &geometry);
static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_EDIT;
static constexpr inline GeometryComponent::Type static_type = GeometryComponent::Type::Edit;
};
} // namespace blender::bke

View File

@ -6,11 +6,15 @@
#include "BKE_geometry_set.hh"
struct Object;
namespace blender::bke {
/**
* \note This doesn't extract instances from the "dupli" system for non-geometry-nodes instances.
*/
GeometrySet object_get_evaluated_geometry_set(const Object &object);
GeometrySet object_get_evaluated_geometry_set(const struct Object &object);
bool object_has_geometry_set_instances(const struct Object &object);
} // namespace blender::bke

View File

@ -27,12 +27,13 @@
#include "BKE_attribute.hh"
struct GeometrySet;
struct Object;
struct Collection;
namespace blender::bke {
struct GeometrySet;
/**
* Holds a reference to conceptually unique geometry or a pointer to object/collection data
* that is instanced with a transform in #Instances.

View File

@ -11,6 +11,15 @@
#include "BLI_compiler_attrs.h"
#include "DNA_modifier_types.h" /* needed for all enum typdefs */
#ifdef __cplusplus
namespace blender::bke {
struct GeometrySet;
}
using GeometrySetHandle = blender::bke::GeometrySet;
#else
typedef struct GeometrySetHandle GeometrySetHandle;
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -23,7 +32,6 @@ struct BlendWriter;
struct CustomData_MeshMasks;
struct DepsNodeHandle;
struct Depsgraph;
struct GeometrySet;
struct ID;
struct ListBase;
struct Main;
@ -242,7 +250,7 @@ typedef struct ModifierTypeInfo {
*/
void (*modifyGeometrySet)(struct ModifierData *md,
const struct ModifierEvalContext *ctx,
struct GeometrySet *geometry_set);
GeometrySetHandle *geometry_set);
/********************* Optional functions *********************/

View File

@ -576,17 +576,15 @@ int ntreeGetPanelIndex(const bNodeTree *ntree, const bNodePanel *panel);
/**
* Add a new panel to the node tree.
* \param name: Name of the new panel.
* \param flag: Flags of the new panel.
*/
bNodePanel *ntreeAddPanel(bNodeTree *ntree, const char *name, int flag);
bNodePanel *ntreeAddPanel(bNodeTree *ntree, const char *name);
/**
* Insert a new panel in the node tree.
* \param name: Name of the new panel.
* \param flag: Flags of the new panel.
* \param index: Index at which to insert the panel.
*/
bNodePanel *ntreeInsertPanel(bNodeTree *ntree, const char *name, int flag, int index);
bNodePanel *ntreeInsertPanel(bNodeTree *ntree, const char *name, int index);
/** Remove a panel from the node tree. */
void ntreeRemovePanel(bNodeTree *ntree, bNodePanel *panel);

View File

@ -291,6 +291,9 @@ class bNodeRuntime : NonCopyable, NonMovable {
bool has_available_linked_outputs = false;
Vector<bNode *> direct_children_in_frame;
bNodeTree *owner_tree = nullptr;
/** Can be used to toposort a subset of nodes. */
int toposort_left_to_right_index = -1;
int toposort_right_to_left_index = -1;
};
namespace node_tree_runtime {
@ -515,6 +518,18 @@ inline blender::Span<bNode *> bNodeTree::root_frames() const
return this->runtime->root_frames;
}
inline blender::Span<bNodeLink *> bNodeTree::all_links()
{
BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this));
return this->runtime->links;
}
inline blender::Span<const bNodeLink *> bNodeTree::all_links() const
{
BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this));
return this->runtime->links;
}
inline blender::Span<const bNodePanel *> bNodeTree::panels() const
{
return blender::Span(panels_array, panels_num);
@ -525,6 +540,8 @@ inline blender::MutableSpan<bNodePanel *> bNodeTree::panels_for_write()
return blender::MutableSpan(panels_array, panels_num);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name #bNode Inline Methods
* \{ */

View File

@ -28,16 +28,31 @@ struct TreeZone {
TreeZone *parent_zone = nullptr;
/** Direct children zones. Does not contain recursively nested zones. */
Vector<TreeZone *> child_zones;
/** Direct children nodes. Does not contain recursively nested nodes. */
/** Direct children nodes excluding nodes that belong to child zones. */
Vector<const bNode *> child_nodes;
/** Links that enter the zone through the zone border. */
Vector<const bNodeLink *> border_links;
bool contains_node_recursively(const bNode &node) const;
bool contains_zone_recursively(const TreeZone &other_zone) const;
};
class TreeZones {
public:
Vector<std::unique_ptr<TreeZone>> zones;
Map<int, int> parent_zone_by_node_id;
Vector<TreeZone *> root_zones;
Vector<const bNode *> nodes_outside_zones;
/**
* Zone index by node. Nodes that are in no zone, are not included. Nodes that are at the border
* of a zone (e.g. Simulation Input) are mapped to the zone they create.
*/
Map<int, int> zone_by_node_id;
/**
* Get the deepest zone that a socket is in. Note that the inputs of a Simulation Input node are
* in a different zone than its output sockets.
*/
const TreeZone *get_zone_by_socket(const bNodeSocket &socket) const;
};
const TreeZones *get_tree_zones(const bNodeTree &tree);

View File

@ -235,6 +235,7 @@ set(SRC
intern/node.cc
intern/node_runtime.cc
intern/node_tree_anonymous_attributes.cc
intern/node_tree_dot_export.cc
intern/node_tree_field_inferencing.cc
intern/node_tree_update.cc
intern/node_tree_zones.cc
@ -387,7 +388,6 @@ set(SRC
BKE_fluid.h
BKE_freestyle.h
BKE_geometry_fields.hh
BKE_geometry_set.h
BKE_geometry_set.hh
BKE_geometry_set_instances.hh
BKE_global.h
@ -452,6 +452,8 @@ set(SRC
BKE_node.h
BKE_node.hh
BKE_node_runtime.hh
BKE_node_tree_anonymous_attributes.hh
BKE_node_tree_dot_export.hh
BKE_node_tree_update.h
BKE_node_tree_zones.hh
BKE_object.h

View File

@ -72,6 +72,9 @@ using blender::float3;
using blender::IndexRange;
using blender::Span;
using blender::VArray;
using blender::bke::GeometryOwnershipType;
using blender::bke::GeometrySet;
using blender::bke::MeshComponent;
/* very slow! enable for testing only! */
//#define USE_MODIFIER_VALIDATE

View File

@ -665,6 +665,23 @@ static void bvhtree_from_editmesh_setup_data(BVHTree *tree,
}
}
static BVHTree *bvhtree_new_common(
float epsilon, int tree_type, int axis, int elems_num, int &elems_num_active)
{
if (elems_num_active != -1) {
BLI_assert(IN_RANGE_INCL(elems_num_active, 0, elems_num));
}
else {
elems_num_active = elems_num;
}
if (elems_num_active == 0) {
return nullptr;
}
return BLI_bvhtree_new(elems_num_active, epsilon, tree_type, axis);
}
/** \} */
/* -------------------------------------------------------------------- */
@ -678,20 +695,15 @@ static BVHTree *bvhtree_from_editmesh_verts_create_tree(float epsilon,
const BitSpan verts_mask,
int verts_num_active)
{
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
const int verts_num = em->bm->totvert;
if (!verts_mask.is_empty()) {
BLI_assert(IN_RANGE_INCL(verts_num_active, 0, verts_num));
}
else {
verts_num_active = verts_num;
}
BVHTree *tree = BLI_bvhtree_new(verts_num_active, epsilon, tree_type, axis);
BVHTree *tree = bvhtree_new_common(epsilon, tree_type, axis, verts_num, verts_num_active);
if (!tree) {
return nullptr;
}
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
for (int i = 0; i < verts_num; i++) {
if (!verts_mask.is_empty() && !verts_mask[i]) {
continue;
@ -712,17 +724,7 @@ static BVHTree *bvhtree_from_mesh_verts_create_tree(float epsilon,
const BitSpan verts_mask,
int verts_num_active)
{
if (!verts_mask.is_empty()) {
BLI_assert(IN_RANGE_INCL(verts_num_active, 0, verts_num));
}
else {
verts_num_active = verts_num;
}
if (verts_num_active == 0) {
return nullptr;
}
BVHTree *tree = BLI_bvhtree_new(verts_num_active, epsilon, tree_type, axis);
BVHTree *tree = bvhtree_new_common(epsilon, tree_type, axis, verts_num, verts_num_active);
if (!tree) {
return nullptr;
}
@ -800,21 +802,15 @@ static BVHTree *bvhtree_from_editmesh_edges_create_tree(float epsilon,
const BitSpan edges_mask,
int edges_num_active)
{
BM_mesh_elem_table_ensure(em->bm, BM_EDGE);
const int edges_num = em->bm->totedge;
if (!edges_mask.is_empty()) {
BLI_assert(IN_RANGE_INCL(edges_num_active, 0, edges_num));
}
else {
edges_num_active = edges_num;
}
BVHTree *tree = BLI_bvhtree_new(edges_num_active, epsilon, tree_type, axis);
BVHTree *tree = bvhtree_new_common(epsilon, tree_type, axis, edges_num, edges_num_active);
if (!tree) {
return nullptr;
}
BM_mesh_elem_table_ensure(em->bm, BM_EDGE);
int i;
BMIter iter;
BMEdge *eed;
@ -841,18 +837,7 @@ static BVHTree *bvhtree_from_mesh_edges_create_tree(const float (*positions)[3],
int tree_type,
int axis)
{
if (!edges_mask.is_empty()) {
BLI_assert(IN_RANGE_INCL(edges_num_active, 0, edges.size()));
}
else {
edges_num_active = edges.size();
}
if (edges_num_active == 0) {
return nullptr;
}
/* Create a BVH-tree of the given target */
BVHTree *tree = BLI_bvhtree_new(edges_num_active, epsilon, tree_type, axis);
BVHTree *tree = bvhtree_new_common(epsilon, tree_type, axis, edges.size(), edges_num_active);
if (!tree) {
return nullptr;
}
@ -936,20 +921,7 @@ static BVHTree *bvhtree_from_mesh_faces_create_tree(float epsilon,
const BitSpan faces_mask,
int faces_num_active)
{
if (faces_num == 0) {
return nullptr;
}
if (!faces_mask.is_empty()) {
BLI_assert(IN_RANGE_INCL(faces_num_active, 0, faces_num));
}
else {
faces_num_active = faces_num;
}
/* Create a BVH-tree of the given target. */
// printf("%s: building BVH, total=%d\n", __func__, numFaces);
BVHTree *tree = BLI_bvhtree_new(faces_num_active, epsilon, tree_type, axis);
BVHTree *tree = bvhtree_new_common(epsilon, tree_type, axis, faces_num, faces_num_active);
if (!tree) {
return nullptr;
}
@ -990,20 +962,8 @@ static BVHTree *bvhtree_from_editmesh_looptri_create_tree(float epsilon,
int looptri_num_active)
{
const int looptri_num = em->tottri;
if (looptri_num == 0) {
return nullptr;
}
if (!looptri_mask.is_empty()) {
BLI_assert(IN_RANGE_INCL(looptri_num_active, 0, looptri_num));
}
else {
looptri_num_active = looptri_num;
}
/* Create a BVH-tree of the given target */
// printf("%s: building BVH, total=%d\n", __func__, numFaces);
BVHTree *tree = BLI_bvhtree_new(looptri_num_active, epsilon, tree_type, axis);
BVHTree *tree = bvhtree_new_common(epsilon, tree_type, axis, looptri_num, looptri_num_active);
if (!tree) {
return nullptr;
}
@ -1042,37 +1002,30 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon,
const BitSpan looptri_mask,
int looptri_num_active)
{
if (!looptri_mask.is_empty()) {
BLI_assert(IN_RANGE_INCL(looptri_num_active, 0, looptris.size()));
}
else {
looptri_num_active = looptris.size();
}
if (looptri_num_active == 0) {
if (positions == nullptr) {
return nullptr;
}
/* Create a BVH-tree of the given target */
// printf("%s: building BVH, total=%d\n", __func__, numFaces);
BVHTree *tree = BLI_bvhtree_new(looptri_num_active, epsilon, tree_type, axis);
BVHTree *tree = bvhtree_new_common(
epsilon, tree_type, axis, looptris.size(), looptri_num_active);
if (!tree) {
return nullptr;
}
if (positions && !looptris.is_empty()) {
for (const int i : looptris.index_range()) {
float co[3][3];
if (!looptri_mask.is_empty() && !looptri_mask[i]) {
continue;
}
copy_v3_v3(co[0], positions[corner_verts[looptris[i].tri[0]]]);
copy_v3_v3(co[1], positions[corner_verts[looptris[i].tri[1]]]);
copy_v3_v3(co[2], positions[corner_verts[looptris[i].tri[2]]]);
BLI_bvhtree_insert(tree, i, co[0], 3);
for (const int i : looptris.index_range()) {
float co[3][3];
if (!looptri_mask.is_empty() && !looptri_mask[i]) {
continue;
}
copy_v3_v3(co[0], positions[corner_verts[looptris[i].tri[0]]]);
copy_v3_v3(co[1], positions[corner_verts[looptris[i].tri[1]]]);
copy_v3_v3(co[2], positions[corner_verts[looptris[i].tri[2]]]);
BLI_bvhtree_insert(tree, i, co[0], 3);
}
BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active);
return tree;
@ -1402,7 +1355,8 @@ BVHTree *BKE_bvhtree_from_pointcloud_get(BVHTreeFromPointCloud *data,
const PointCloud *pointcloud,
const int tree_type)
{
BVHTree *tree = BLI_bvhtree_new(pointcloud->totpoint, 0.0f, tree_type, 6);
int tot_point = pointcloud->totpoint;
BVHTree *tree = bvhtree_new_common(0.0f, tree_type, 6, tot_point, tot_point);
if (!tree) {
return nullptr;
}
@ -1411,7 +1365,8 @@ BVHTree *BKE_bvhtree_from_pointcloud_get(BVHTreeFromPointCloud *data,
for (const int i : positions.index_range()) {
BLI_bvhtree_insert(tree, i, positions[i], 1);
}
BLI_assert(BLI_bvhtree_get_len(tree) == pointcloud->totpoint);
BLI_assert(BLI_bvhtree_get_len(tree) == tot_point);
bvhtree_balance(tree, false);
data->coords = (const float(*)[3])positions.data();

View File

@ -17,10 +17,10 @@ struct Tex;
struct Image;
struct Material;
BLI_CPP_TYPE_MAKE(GeometrySet, CPPTypeFlags::Printable);
BLI_CPP_TYPE_MAKE(blender::bke::GeometrySet, CPPTypeFlags::Printable);
BLI_CPP_TYPE_MAKE(blender::bke::InstanceReference, CPPTypeFlags::None)
BLI_VECTOR_CPP_TYPE_MAKE(GeometrySet);
BLI_VECTOR_CPP_TYPE_MAKE(blender::bke::GeometrySet);
BLI_CPP_TYPE_MAKE(Object *, CPPTypeFlags::BasicType)
BLI_CPP_TYPE_MAKE(Collection *, CPPTypeFlags::BasicType)
@ -37,10 +37,10 @@ void BKE_cpp_types_init()
blender::register_cpp_types();
FN_register_cpp_types();
BLI_CPP_TYPE_REGISTER(GeometrySet);
BLI_CPP_TYPE_REGISTER(blender::bke::GeometrySet);
BLI_CPP_TYPE_REGISTER(blender::bke::InstanceReference);
BLI_VECTOR_CPP_TYPE_REGISTER(GeometrySet);
BLI_VECTOR_CPP_TYPE_REGISTER(blender::bke::GeometrySet);
BLI_CPP_TYPE_REGISTER(Object *);
BLI_CPP_TYPE_REGISTER(Collection *);

View File

@ -231,7 +231,7 @@ Curves *BKE_curves_copy_for_eval(const Curves *curves_src)
static void curves_evaluate_modifiers(Depsgraph *depsgraph,
Scene *scene,
Object *object,
GeometrySet &geometry_set)
blender::bke::GeometrySet &geometry_set)
{
/* Modifier evaluation modes. */
const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
@ -267,6 +267,8 @@ static void curves_evaluate_modifiers(Depsgraph *depsgraph,
void BKE_curves_data_update(Depsgraph *depsgraph, Scene *scene, Object *object)
{
using namespace blender;
using namespace blender::bke;
/* Free any evaluated data and restore original data. */
BKE_object_free_derived_caches(object);
@ -279,7 +281,7 @@ void BKE_curves_data_update(Depsgraph *depsgraph, Scene *scene, Object *object)
* on evaluated curves. */
GeometryComponentEditData &edit_component =
geometry_set.get_component_for_write<GeometryComponentEditData>();
edit_component.curves_edit_hints_ = std::make_unique<blender::bke::CurvesEditHints>(
edit_component.curves_edit_hints_ = std::make_unique<CurvesEditHints>(
*static_cast<const Curves *>(DEG_get_original_object(object)->data));
}
curves_evaluate_modifiers(depsgraph, scene, object, geometry_set);
@ -287,7 +289,7 @@ void BKE_curves_data_update(Depsgraph *depsgraph, Scene *scene, Object *object)
/* Assign evaluated object. */
Curves *curves_eval = const_cast<Curves *>(geometry_set.get_curves_for_read());
if (curves_eval == nullptr) {
curves_eval = blender::bke::curves_new_nomain(0, 0);
curves_eval = curves_new_nomain(0, 0);
BKE_object_eval_assign_data(object, &curves_eval->id, true);
}
else {

View File

@ -686,11 +686,11 @@ static bool do_curve_implicit_mesh_conversion(const Curve *curve,
return false;
}
static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
const Scene *scene,
Object *ob,
const ListBase *dispbase,
const bool for_render)
static blender::bke::GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
const Scene *scene,
Object *ob,
const ListBase *dispbase,
const bool for_render)
{
const Curve *cu = (const Curve *)ob->data;
const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
@ -714,7 +714,7 @@ static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData) :
pretessellatePoint->next;
GeometrySet geometry_set;
blender::bke::GeometrySet geometry_set;
if (ob->type == OB_SURF || do_curve_implicit_mesh_conversion(cu, md, scene, required_mode)) {
Mesh *mesh = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
geometry_set.replace_mesh(mesh);
@ -801,11 +801,11 @@ static void displist_surf_indices(DispList *dl)
}
}
static GeometrySet evaluate_surface_object(Depsgraph *depsgraph,
const Scene *scene,
Object *ob,
const bool for_render,
ListBase *r_dispbase)
static blender::bke::GeometrySet evaluate_surface_object(Depsgraph *depsgraph,
const Scene *scene,
Object *ob,
const bool for_render,
ListBase *r_dispbase)
{
BLI_assert(ob->type == OB_SURF);
const Curve *cu = (const Curve *)ob->data;
@ -883,7 +883,7 @@ static GeometrySet evaluate_surface_object(Depsgraph *depsgraph,
}
curve_to_filledpoly(cu, r_dispbase);
GeometrySet geometry_set = curve_calc_modifiers_post(
blender::bke::GeometrySet geometry_set = curve_calc_modifiers_post(
depsgraph, scene, ob, r_dispbase, for_render);
if (!geometry_set.has_mesh()) {
geometry_set.replace_mesh(BKE_mesh_new_nomain(0, 0, 0, 0));
@ -1110,11 +1110,11 @@ static void calc_bevfac_mapping(const Curve *cu,
}
}
static GeometrySet evaluate_curve_type_object(Depsgraph *depsgraph,
const Scene *scene,
Object *ob,
const bool for_render,
ListBase *r_dispbase)
static blender::bke::GeometrySet evaluate_curve_type_object(Depsgraph *depsgraph,
const Scene *scene,
Object *ob,
const bool for_render,
ListBase *r_dispbase)
{
BLI_assert(ELEM(ob->type, OB_CURVES_LEGACY, OB_FONT));
const Curve *cu = (const Curve *)ob->data;
@ -1339,11 +1339,13 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
ListBase *dispbase = &ob->runtime.curve_cache->disp;
if (ob->type == OB_SURF) {
GeometrySet geometry = evaluate_surface_object(depsgraph, scene, ob, for_render, dispbase);
ob->runtime.geometry_set_eval = new GeometrySet(std::move(geometry));
blender::bke::GeometrySet geometry = evaluate_surface_object(
depsgraph, scene, ob, for_render, dispbase);
ob->runtime.geometry_set_eval = new blender::bke::GeometrySet(std::move(geometry));
}
else {
GeometrySet geometry = evaluate_curve_type_object(depsgraph, scene, ob, for_render, dispbase);
blender::bke::GeometrySet geometry = evaluate_curve_type_object(
depsgraph, scene, ob, for_render, dispbase);
if (geometry.has_curves()) {
/* Create a copy of the original curve and add necessary pointers to evaluated and edit mode
@ -1369,7 +1371,7 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
BKE_object_eval_assign_data(ob, &cow_curve.id, true);
}
ob->runtime.geometry_set_eval = new GeometrySet(std::move(geometry));
ob->runtime.geometry_set_eval = new blender::bke::GeometrySet(std::move(geometry));
}
BKE_object_boundbox_calc_from_evaluated_geometry(ob);

View File

@ -18,11 +18,13 @@
#include "attribute_access_intern.hh"
namespace blender::bke {
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
* \{ */
CurveComponent::CurveComponent() : GeometryComponent(GEO_COMPONENT_TYPE_CURVE) {}
CurveComponent::CurveComponent() : GeometryComponent(Type::Curve) {}
CurveComponent::~CurveComponent()
{
@ -133,8 +135,6 @@ const Curve *CurveComponent::get_curve_for_render() const
/** \} */
namespace blender::bke {
/* -------------------------------------------------------------------- */
/** \name Curve Normals Access
* \{ */
@ -612,17 +612,17 @@ MutableAttributeAccessor CurvesGeometry::attributes_for_write()
return MutableAttributeAccessor(this, get_curves_accessor_functions_ref());
}
} // namespace blender::bke
std::optional<blender::bke::AttributeAccessor> CurveComponent::attributes() const
std::optional<AttributeAccessor> CurveComponent::attributes() const
{
return blender::bke::AttributeAccessor(curves_ ? &curves_->geometry : nullptr,
blender::bke::get_curves_accessor_functions_ref());
return AttributeAccessor(curves_ ? &curves_->geometry : nullptr,
get_curves_accessor_functions_ref());
}
std::optional<blender::bke::MutableAttributeAccessor> CurveComponent::attributes_for_write()
std::optional<MutableAttributeAccessor> CurveComponent::attributes_for_write()
{
Curves *curves = this->get_for_write();
return blender::bke::MutableAttributeAccessor(curves ? &curves->geometry : nullptr,
blender::bke::get_curves_accessor_functions_ref());
return MutableAttributeAccessor(curves ? &curves->geometry : nullptr,
get_curves_accessor_functions_ref());
}
} // namespace blender::bke

View File

@ -5,12 +5,9 @@
#include "BKE_curves.hh"
#include "BKE_geometry_set.hh"
using namespace blender;
using namespace blender::bke;
namespace blender::bke {
GeometryComponentEditData::GeometryComponentEditData() : GeometryComponent(GEO_COMPONENT_TYPE_EDIT)
{
}
GeometryComponentEditData::GeometryComponentEditData() : GeometryComponent(Type::Edit) {}
GeometryComponent *GeometryComponentEditData::copy() const
{
@ -56,7 +53,7 @@ void GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(
if (curves_id == nullptr) {
return;
}
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
const CurvesGeometry &curves = curves_id->geometry.wrap();
const int points_num = curves.points_num();
if (points_num != edit_component.curves_edit_hints_->curves_id_orig.geometry.point_num) {
return;
@ -64,3 +61,5 @@ void GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(
edit_component.curves_edit_hints_->positions.emplace(points_num);
edit_component.curves_edit_hints_->positions->as_mutable_span().copy_from(curves.positions());
}
} // namespace blender::bke

View File

@ -24,11 +24,13 @@
#include "BLI_cpp_type_make.hh"
namespace blender::bke {
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
* \{ */
InstancesComponent::InstancesComponent() : GeometryComponent(GEO_COMPONENT_TYPE_INSTANCES) {}
InstancesComponent::InstancesComponent() : GeometryComponent(Type::Instance) {}
InstancesComponent::~InstancesComponent()
{
@ -39,7 +41,7 @@ GeometryComponent *InstancesComponent::copy() const
{
InstancesComponent *new_component = new InstancesComponent();
if (instances_ != nullptr) {
new_component->instances_ = new blender::bke::Instances(*instances_);
new_component->instances_ = new Instances(*instances_);
new_component->ownership_ = GeometryOwnershipType::Owned;
}
return new_component;
@ -79,23 +81,22 @@ void InstancesComponent::ensure_owns_direct_data()
}
}
const blender::bke::Instances *InstancesComponent::get_for_read() const
const Instances *InstancesComponent::get_for_read() const
{
return instances_;
}
blender::bke::Instances *InstancesComponent::get_for_write()
Instances *InstancesComponent::get_for_write()
{
BLI_assert(this->is_mutable());
if (ownership_ == GeometryOwnershipType::ReadOnly) {
instances_ = new blender::bke::Instances(*instances_);
instances_ = new Instances(*instances_);
ownership_ = GeometryOwnershipType::Owned;
}
return instances_;
}
void InstancesComponent::replace(blender::bke::Instances *instances,
GeometryOwnershipType ownership)
void InstancesComponent::replace(Instances *instances, GeometryOwnershipType ownership)
{
BLI_assert(this->is_mutable());
this->clear();
@ -103,8 +104,6 @@ void InstancesComponent::replace(blender::bke::Instances *instances,
ownership_ = ownership;
}
namespace blender::bke {
static float3 get_transform_position(const float4x4 &transform)
{
return transform.location();
@ -240,30 +239,26 @@ static const AttributeAccessorFunctions &get_instances_accessor_functions_ref()
return fn;
}
blender::bke::AttributeAccessor Instances::attributes() const
AttributeAccessor Instances::attributes() const
{
return blender::bke::AttributeAccessor(this,
blender::bke::get_instances_accessor_functions_ref());
return AttributeAccessor(this, get_instances_accessor_functions_ref());
}
blender::bke::MutableAttributeAccessor Instances::attributes_for_write()
MutableAttributeAccessor Instances::attributes_for_write()
{
return blender::bke::MutableAttributeAccessor(
this, blender::bke::get_instances_accessor_functions_ref());
return MutableAttributeAccessor(this, get_instances_accessor_functions_ref());
}
} // namespace blender::bke
std::optional<blender::bke::AttributeAccessor> InstancesComponent::attributes() const
std::optional<AttributeAccessor> InstancesComponent::attributes() const
{
return blender::bke::AttributeAccessor(instances_,
blender::bke::get_instances_accessor_functions_ref());
return AttributeAccessor(instances_, get_instances_accessor_functions_ref());
}
std::optional<blender::bke::MutableAttributeAccessor> InstancesComponent::attributes_for_write()
std::optional<MutableAttributeAccessor> InstancesComponent::attributes_for_write()
{
return blender::bke::MutableAttributeAccessor(
instances_, blender::bke::get_instances_accessor_functions_ref());
return MutableAttributeAccessor(instances_, get_instances_accessor_functions_ref());
}
/** \} */
} // namespace blender::bke

View File

@ -21,11 +21,13 @@
#include "attribute_access_intern.hh"
namespace blender::bke {
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
* \{ */
MeshComponent::MeshComponent() : GeometryComponent(GEO_COMPONENT_TYPE_MESH) {}
MeshComponent::MeshComponent() : GeometryComponent(Type::Mesh) {}
MeshComponent::~MeshComponent()
{
@ -114,8 +116,6 @@ void MeshComponent::ensure_owns_direct_data()
/** \name Mesh Normals Field Input
* \{ */
namespace blender::bke {
VArray<float3> mesh_normals_varray(const Mesh &mesh,
const IndexMask &mask,
const eAttrDomain domain)
@ -196,7 +196,7 @@ void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
}
/* Deselect loose vertices without corners that are still selected from the 'true' default. */
const bke::LooseVertCache &loose_verts = mesh.verts_no_face();
const LooseVertCache &loose_verts = mesh.verts_no_face();
if (loose_verts.count > 0) {
const BitSpan bits = loose_verts.is_loose_bits;
threading::parallel_for(bits.index_range(), 2048, [&](const IndexRange range) {
@ -334,7 +334,7 @@ void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
}
}
const bke::LooseEdgeCache &loose_edges = mesh.loose_edges();
const LooseEdgeCache &loose_edges = mesh.loose_edges();
if (loose_edges.count > 0) {
/* Deselect loose edges without corners that are still selected from the 'true' default. */
threading::parallel_for(IndexRange(mesh.totedge), 2048, [&](const IndexRange range) {
@ -1274,16 +1274,19 @@ blender::bke::MutableAttributeAccessor Mesh::attributes_for_write()
blender::bke::get_mesh_accessor_functions_ref());
}
std::optional<blender::bke::AttributeAccessor> MeshComponent::attributes() const
namespace blender::bke {
std::optional<AttributeAccessor> MeshComponent::attributes() const
{
return blender::bke::AttributeAccessor(mesh_, blender::bke::get_mesh_accessor_functions_ref());
return AttributeAccessor(mesh_, get_mesh_accessor_functions_ref());
}
std::optional<blender::bke::MutableAttributeAccessor> MeshComponent::attributes_for_write()
std::optional<MutableAttributeAccessor> MeshComponent::attributes_for_write()
{
Mesh *mesh = this->get_for_write();
return blender::bke::MutableAttributeAccessor(mesh,
blender::bke::get_mesh_accessor_functions_ref());
return MutableAttributeAccessor(mesh, get_mesh_accessor_functions_ref());
}
/** \} */
} // namespace blender::bke

View File

@ -10,11 +10,13 @@
#include "attribute_access_intern.hh"
namespace blender::bke {
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
* \{ */
PointCloudComponent::PointCloudComponent() : GeometryComponent(GEO_COMPONENT_TYPE_POINT_CLOUD) {}
PointCloudComponent::PointCloudComponent() : GeometryComponent(Type::PointCloud) {}
PointCloudComponent::~PointCloudComponent()
{
@ -103,8 +105,6 @@ void PointCloudComponent::ensure_owns_direct_data()
/** \name Attribute Access
* \{ */
namespace blender::bke {
static void tag_component_positions_changed(void *owner)
{
PointCloud &points = *static_cast<PointCloud *>(owner);
@ -187,13 +187,13 @@ static AttributeAccessorFunctions get_pointcloud_accessor_functions()
return domain == ATTR_DOMAIN_POINT;
};
fn.adapt_domain = [](const void * /*owner*/,
const blender::GVArray &varray,
const GVArray &varray,
const eAttrDomain from_domain,
const eAttrDomain to_domain) {
if (from_domain == to_domain && from_domain == ATTR_DOMAIN_POINT) {
return varray;
}
return blender::GVArray{};
return GVArray{};
};
return fn;
}
@ -218,17 +218,19 @@ blender::bke::MutableAttributeAccessor PointCloud::attributes_for_write()
this, blender::bke::get_pointcloud_accessor_functions_ref());
}
std::optional<blender::bke::AttributeAccessor> PointCloudComponent::attributes() const
namespace blender::bke {
std::optional<AttributeAccessor> PointCloudComponent::attributes() const
{
return blender::bke::AttributeAccessor(pointcloud_,
blender::bke::get_pointcloud_accessor_functions_ref());
return AttributeAccessor(pointcloud_, get_pointcloud_accessor_functions_ref());
}
std::optional<blender::bke::MutableAttributeAccessor> PointCloudComponent::attributes_for_write()
std::optional<MutableAttributeAccessor> PointCloudComponent::attributes_for_write()
{
PointCloud *pointcloud = this->get_for_write();
return blender::bke::MutableAttributeAccessor(
pointcloud, blender::bke::get_pointcloud_accessor_functions_ref());
return MutableAttributeAccessor(pointcloud, get_pointcloud_accessor_functions_ref());
}
/** \} */
} // namespace blender::bke

View File

@ -8,11 +8,13 @@
#include "BKE_lib_id.h"
#include "BKE_volume.h"
namespace blender::bke {
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
* \{ */
VolumeComponent::VolumeComponent() : GeometryComponent(GEO_COMPONENT_TYPE_VOLUME) {}
VolumeComponent::VolumeComponent() : GeometryComponent(GeometryComponent::Type::Volume) {}
VolumeComponent::~VolumeComponent()
{
@ -91,3 +93,5 @@ void VolumeComponent::ensure_owns_direct_data()
}
/** \} */
} // namespace blender::bke

View File

@ -35,15 +35,15 @@ CurvesFieldContext::CurvesFieldContext(const CurvesGeometry &curves, const eAttr
}
GeometryFieldContext::GeometryFieldContext(const void *geometry,
const GeometryComponentType type,
const GeometryComponent::Type type,
const eAttrDomain domain)
: geometry_(geometry), type_(type), domain_(domain)
{
BLI_assert(ELEM(type,
GEO_COMPONENT_TYPE_MESH,
GEO_COMPONENT_TYPE_CURVE,
GEO_COMPONENT_TYPE_POINT_CLOUD,
GEO_COMPONENT_TYPE_INSTANCES));
GeometryComponent::Type::Mesh,
GeometryComponent::Type::Curve,
GeometryComponent::Type::PointCloud,
GeometryComponent::Type::Instance));
}
GeometryFieldContext::GeometryFieldContext(const GeometryComponent &component,
@ -51,50 +51,52 @@ GeometryFieldContext::GeometryFieldContext(const GeometryComponent &component,
: type_(component.type()), domain_(domain)
{
switch (component.type()) {
case GEO_COMPONENT_TYPE_MESH: {
case GeometryComponent::Type::Mesh: {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
geometry_ = mesh_component.get_for_read();
break;
}
case GEO_COMPONENT_TYPE_CURVE: {
case GeometryComponent::Type::Curve: {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const Curves *curves = curve_component.get_for_read();
geometry_ = curves ? &curves->geometry.wrap() : nullptr;
break;
}
case GEO_COMPONENT_TYPE_POINT_CLOUD: {
case GeometryComponent::Type::PointCloud: {
const PointCloudComponent &pointcloud_component = static_cast<const PointCloudComponent &>(
component);
geometry_ = pointcloud_component.get_for_read();
break;
}
case GEO_COMPONENT_TYPE_INSTANCES: {
case GeometryComponent::Type::Instance: {
const InstancesComponent &instances_component = static_cast<const InstancesComponent &>(
component);
geometry_ = instances_component.get_for_read();
break;
}
case GEO_COMPONENT_TYPE_VOLUME:
case GEO_COMPONENT_TYPE_EDIT:
case GeometryComponent::Type::Volume:
case GeometryComponent::Type::Edit:
BLI_assert_unreachable();
break;
}
}
GeometryFieldContext::GeometryFieldContext(const Mesh &mesh, eAttrDomain domain)
: geometry_(&mesh), type_(GEO_COMPONENT_TYPE_MESH), domain_(domain)
: geometry_(&mesh), type_(GeometryComponent::Type::Mesh), domain_(domain)
{
}
GeometryFieldContext::GeometryFieldContext(const CurvesGeometry &curves, eAttrDomain domain)
: geometry_(&curves), type_(GEO_COMPONENT_TYPE_CURVE), domain_(domain)
: geometry_(&curves), type_(GeometryComponent::Type::Curve), domain_(domain)
{
}
GeometryFieldContext::GeometryFieldContext(const PointCloud &points)
: geometry_(&points), type_(GEO_COMPONENT_TYPE_POINT_CLOUD), domain_(ATTR_DOMAIN_POINT)
: geometry_(&points), type_(GeometryComponent::Type::PointCloud), domain_(ATTR_DOMAIN_POINT)
{
}
GeometryFieldContext::GeometryFieldContext(const Instances &instances)
: geometry_(&instances), type_(GEO_COMPONENT_TYPE_INSTANCES), domain_(ATTR_DOMAIN_INSTANCE)
: geometry_(&instances),
type_(GeometryComponent::Type::Instance),
domain_(ATTR_DOMAIN_INSTANCE)
{
}
@ -117,24 +119,26 @@ std::optional<AttributeAccessor> GeometryFieldContext::attributes() const
const Mesh *GeometryFieldContext::mesh() const
{
return this->type() == GEO_COMPONENT_TYPE_MESH ? static_cast<const Mesh *>(geometry_) : nullptr;
return this->type() == GeometryComponent::Type::Mesh ? static_cast<const Mesh *>(geometry_) :
nullptr;
}
const CurvesGeometry *GeometryFieldContext::curves() const
{
return this->type() == GEO_COMPONENT_TYPE_CURVE ?
return this->type() == GeometryComponent::Type::Curve ?
static_cast<const CurvesGeometry *>(geometry_) :
nullptr;
}
const PointCloud *GeometryFieldContext::pointcloud() const
{
return this->type() == GEO_COMPONENT_TYPE_POINT_CLOUD ?
return this->type() == GeometryComponent::Type::PointCloud ?
static_cast<const PointCloud *>(geometry_) :
nullptr;
}
const Instances *GeometryFieldContext::instances() const
{
return this->type() == GEO_COMPONENT_TYPE_INSTANCES ? static_cast<const Instances *>(geometry_) :
nullptr;
return this->type() == GeometryComponent::Type::Instance ?
static_cast<const Instances *>(geometry_) :
nullptr;
}
GVArray GeometryFieldInput::get_varray_for_context(const fn::FieldContext &context,
@ -564,11 +568,11 @@ bool try_capture_field_on_geometry(GeometryComponent &component,
std::optional<eAttrDomain> try_detect_field_domain(const GeometryComponent &component,
const fn::GField &field)
{
const GeometryComponentType component_type = component.type();
if (component_type == GEO_COMPONENT_TYPE_POINT_CLOUD) {
const GeometryComponent::Type component_type = component.type();
if (component_type == GeometryComponent::Type::PointCloud) {
return ATTR_DOMAIN_POINT;
}
if (component_type == GEO_COMPONENT_TYPE_INSTANCES) {
if (component_type == GeometryComponent::Type::Instance) {
return ATTR_DOMAIN_INSTANCE;
}
const std::shared_ptr<const fn::FieldInputs> &field_inputs = field.node().field_inputs();
@ -589,7 +593,7 @@ std::optional<eAttrDomain> try_detect_field_domain(const GeometryComponent &comp
output_domain = domain;
return true;
};
if (component_type == GEO_COMPONENT_TYPE_MESH) {
if (component_type == GeometryComponent::Type::Mesh) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
const Mesh *mesh = mesh_component.get_for_read();
if (mesh == nullptr) {
@ -612,7 +616,7 @@ std::optional<eAttrDomain> try_detect_field_domain(const GeometryComponent &comp
}
}
}
if (component_type == GEO_COMPONENT_TYPE_CURVE) {
if (component_type == GeometryComponent::Type::Curve) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const Curves *curves = curve_component.get_for_read();
if (curves == nullptr) {

View File

@ -11,6 +11,7 @@
#include "BKE_attribute.h"
#include "BKE_curves.hh"
#include "BKE_geometry_set.hh"
#include "BKE_geometry_set_instances.hh"
#include "BKE_instances.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.hh"
@ -27,36 +28,28 @@
#include "MEM_guardedalloc.h"
using blender::float3;
using blender::float4x4;
using blender::Map;
using blender::MutableSpan;
using blender::Span;
using blender::StringRef;
using blender::Vector;
using blender::bke::InstanceReference;
using blender::bke::Instances;
/* -------------------------------------------------------------------- */
/** \name Geometry Component
* \{ */
GeometryComponent::GeometryComponent(GeometryComponentType type) : type_(type) {}
namespace blender::bke {
GeometryComponentPtr GeometryComponent::create(GeometryComponentType component_type)
GeometryComponent::GeometryComponent(Type type) : type_(type) {}
GeometryComponentPtr GeometryComponent::create(Type component_type)
{
switch (component_type) {
case GEO_COMPONENT_TYPE_MESH:
case Type::Mesh:
return new MeshComponent();
case GEO_COMPONENT_TYPE_POINT_CLOUD:
case Type::PointCloud:
return new PointCloudComponent();
case GEO_COMPONENT_TYPE_INSTANCES:
case Type::Instance:
return new InstancesComponent();
case GEO_COMPONENT_TYPE_VOLUME:
case Type::Volume:
return new VolumeComponent();
case GEO_COMPONENT_TYPE_CURVE:
case Type::Curve:
return new CurveComponent();
case GEO_COMPONENT_TYPE_EDIT:
case Type::Edit:
return new GeometryComponentEditData();
}
BLI_assert_unreachable();
@ -68,23 +61,23 @@ int GeometryComponent::attribute_domain_size(const eAttrDomain domain) const
if (this->is_empty()) {
return 0;
}
const std::optional<blender::bke::AttributeAccessor> attributes = this->attributes();
const std::optional<AttributeAccessor> attributes = this->attributes();
if (attributes.has_value()) {
return attributes->domain_size(domain);
}
return 0;
}
std::optional<blender::bke::AttributeAccessor> GeometryComponent::attributes() const
std::optional<AttributeAccessor> GeometryComponent::attributes() const
{
return std::nullopt;
};
std::optional<blender::bke::MutableAttributeAccessor> GeometryComponent::attributes_for_write()
std::optional<MutableAttributeAccessor> GeometryComponent::attributes_for_write()
{
return std::nullopt;
}
GeometryComponentType GeometryComponent::type() const
GeometryComponent::Type GeometryComponent::type() const
{
return type_;
}
@ -117,9 +110,9 @@ GeometrySet::~GeometrySet() = default;
GeometrySet &GeometrySet::operator=(const GeometrySet &other) = default;
GeometrySet &GeometrySet::operator=(GeometrySet &&other) = default;
GeometryComponent &GeometrySet::get_component_for_write(GeometryComponentType component_type)
GeometryComponent &GeometrySet::get_component_for_write(GeometryComponent::Type component_type)
{
GeometryComponentPtr &component_ptr = components_[component_type];
GeometryComponentPtr &component_ptr = components_[size_t(component_type)];
if (!component_ptr) {
/* If the component did not exist before, create a new one. */
component_ptr = GeometryComponent::create(component_type);
@ -136,7 +129,7 @@ GeometryComponent &GeometrySet::get_component_for_write(GeometryComponentType co
return *component_ptr;
}
GeometryComponent *GeometrySet::get_component_ptr(GeometryComponentType type)
GeometryComponent *GeometrySet::get_component_ptr(GeometryComponent::Type type)
{
if (this->has(type)) {
return &this->get_component_for_write(type);
@ -145,23 +138,23 @@ GeometryComponent *GeometrySet::get_component_ptr(GeometryComponentType type)
}
const GeometryComponent *GeometrySet::get_component_for_read(
GeometryComponentType component_type) const
GeometryComponent::Type component_type) const
{
return components_[component_type].get();
return components_[size_t(component_type)].get();
}
bool GeometrySet::has(const GeometryComponentType component_type) const
bool GeometrySet::has(const GeometryComponent::Type component_type) const
{
const GeometryComponentPtr &component = components_[component_type];
const GeometryComponentPtr &component = components_[size_t(component_type)];
return component.has_value() && !component->is_empty();
}
void GeometrySet::remove(const GeometryComponentType component_type)
void GeometrySet::remove(const GeometryComponent::Type component_type)
{
components_[component_type].reset();
components_[size_t(component_type)].reset();
}
void GeometrySet::keep_only(const blender::Span<GeometryComponentType> component_types)
void GeometrySet::keep_only(const Span<GeometryComponent::Type> component_types)
{
for (GeometryComponentPtr &component_ptr : components_) {
if (component_ptr) {
@ -172,12 +165,11 @@ void GeometrySet::keep_only(const blender::Span<GeometryComponentType> component
}
}
void GeometrySet::keep_only_during_modify(
const blender::Span<GeometryComponentType> component_types)
void GeometrySet::keep_only_during_modify(const Span<GeometryComponent::Type> component_types)
{
Vector<GeometryComponentType> extended_types = component_types;
extended_types.append_non_duplicates(GEO_COMPONENT_TYPE_INSTANCES);
extended_types.append_non_duplicates(GEO_COMPONENT_TYPE_EDIT);
Vector<GeometryComponent::Type> extended_types = component_types;
extended_types.append_non_duplicates(GeometryComponent::Type::Instance);
extended_types.append_non_duplicates(GeometryComponent::Type::Edit);
this->keep_only(extended_types);
}
@ -188,9 +180,9 @@ void GeometrySet::remove_geometry_during_modify()
void GeometrySet::add(const GeometryComponent &component)
{
BLI_assert(!components_[component.type()]);
BLI_assert(!components_[size_t(component.type())]);
component.add_user();
components_[component.type()] = const_cast<GeometryComponent *>(&component);
components_[size_t(component.type())] = const_cast<GeometryComponent *>(&component);
}
Vector<const GeometryComponent *> GeometrySet::get_components_for_read() const
@ -339,7 +331,7 @@ const Instances *GeometrySet::get_instances_for_read() const
return (component == nullptr) ? nullptr : component->get_for_read();
}
const blender::bke::CurvesEditHints *GeometrySet::get_curve_edit_hints_for_read() const
const CurvesEditHints *GeometrySet::get_curve_edit_hints_for_read() const
{
const GeometryComponentEditData *component =
this->get_component_for_read<GeometryComponentEditData>();
@ -375,7 +367,7 @@ bool GeometrySet::has_realized_data() const
{
for (const GeometryComponentPtr &component_ptr : components_) {
if (component_ptr) {
if (component_ptr->type() != GEO_COMPONENT_TYPE_INSTANCES) {
if (component_ptr->type() != GeometryComponent::Type::Instance) {
return true;
}
}
@ -538,7 +530,7 @@ Instances *GeometrySet::get_instances_for_write()
return component == nullptr ? nullptr : component->get_for_write();
}
blender::bke::CurvesEditHints *GeometrySet::get_curve_edit_hints_for_write()
CurvesEditHints *GeometrySet::get_curve_edit_hints_for_write()
{
if (!this->has<GeometryComponentEditData>()) {
return nullptr;
@ -548,13 +540,11 @@ blender::bke::CurvesEditHints *GeometrySet::get_curve_edit_hints_for_write()
return component.curves_edit_hints_.get();
}
void GeometrySet::attribute_foreach(const Span<GeometryComponentType> component_types,
void GeometrySet::attribute_foreach(const Span<GeometryComponent::Type> component_types,
const bool include_instances,
const AttributeForeachCallback callback) const
{
using namespace blender;
using namespace blender::bke;
for (const GeometryComponentType component_type : component_types) {
for (const GeometryComponent::Type component_type : component_types) {
if (!this->has(component_type)) {
continue;
}
@ -577,14 +567,12 @@ void GeometrySet::attribute_foreach(const Span<GeometryComponentType> component_
}
void GeometrySet::gather_attributes_for_propagation(
const Span<GeometryComponentType> component_types,
const GeometryComponentType dst_component_type,
const Span<GeometryComponent::Type> component_types,
const GeometryComponent::Type dst_component_type,
bool include_instances,
const blender::bke::AnonymousAttributePropagationInfo &propagation_info,
blender::Map<blender::bke::AttributeIDRef, blender::bke::AttributeKind> &r_attributes) const
const AnonymousAttributePropagationInfo &propagation_info,
Map<AttributeIDRef, AttributeKind> &r_attributes) const
{
using namespace blender;
using namespace blender::bke;
/* Only needed right now to check if an attribute is built-in on this component type.
* TODO: Get rid of the dummy component. */
const GeometryComponentPtr dummy_component = GeometryComponent::create(dst_component_type);
@ -611,7 +599,8 @@ void GeometrySet::gather_attributes_for_propagation(
}
eAttrDomain domain = meta_data.domain;
if (dst_component_type != GEO_COMPONENT_TYPE_INSTANCES && domain == ATTR_DOMAIN_INSTANCE) {
if (dst_component_type != GeometryComponent::Type::Instance &&
domain == ATTR_DOMAIN_INSTANCE) {
domain = ATTR_DOMAIN_POINT;
}
@ -632,7 +621,7 @@ void GeometrySet::gather_attributes_for_propagation(
static void gather_component_types_recursive(const GeometrySet &geometry_set,
const bool include_instances,
const bool ignore_empty,
Vector<GeometryComponentType> &r_types)
Vector<GeometryComponent::Type> &r_types)
{
for (const GeometryComponent *component : geometry_set.get_components_for_read()) {
if (ignore_empty) {
@ -645,7 +634,7 @@ static void gather_component_types_recursive(const GeometrySet &geometry_set,
if (!include_instances) {
return;
}
const blender::bke::Instances *instances = geometry_set.get_instances_for_read();
const Instances *instances = geometry_set.get_instances_for_read();
if (instances == nullptr) {
return;
}
@ -655,10 +644,10 @@ static void gather_component_types_recursive(const GeometrySet &geometry_set,
});
}
blender::Vector<GeometryComponentType> GeometrySet::gather_component_types(
const bool include_instances, bool ignore_empty) const
Vector<GeometryComponent::Type> GeometrySet::gather_component_types(const bool include_instances,
bool ignore_empty) const
{
Vector<GeometryComponentType> types;
Vector<GeometryComponent::Type> types;
gather_component_types_recursive(*this, include_instances, ignore_empty, types);
return types;
}
@ -691,25 +680,14 @@ void GeometrySet::modify_geometry_sets(ForeachSubGeometryCallback callback)
callback(*geometry_sets.first());
}
else {
blender::threading::parallel_for_each(
geometry_sets, [&](GeometrySet *geometry_set) { callback(*geometry_set); });
threading::parallel_for_each(geometry_sets,
[&](GeometrySet *geometry_set) { callback(*geometry_set); });
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name C API
* \{ */
void BKE_geometry_set_free(GeometrySet *geometry_set)
bool object_has_geometry_set_instances(const Object &object)
{
delete geometry_set;
}
bool BKE_object_has_geometry_set_instances(const Object *ob)
{
const GeometrySet *geometry_set = ob->runtime.geometry_set_eval;
const GeometrySet *geometry_set = object.runtime.geometry_set_eval;
if (geometry_set == nullptr) {
return false;
}
@ -717,25 +695,25 @@ bool BKE_object_has_geometry_set_instances(const Object *ob)
if (component->is_empty()) {
continue;
}
const GeometryComponentType type = component->type();
const GeometryComponent::Type type = component->type();
bool is_instance = false;
switch (type) {
case GEO_COMPONENT_TYPE_MESH:
is_instance = ob->type != OB_MESH;
case GeometryComponent::Type::Mesh:
is_instance = object.type != OB_MESH;
break;
case GEO_COMPONENT_TYPE_POINT_CLOUD:
is_instance = ob->type != OB_POINTCLOUD;
case GeometryComponent::Type::PointCloud:
is_instance = object.type != OB_POINTCLOUD;
break;
case GEO_COMPONENT_TYPE_INSTANCES:
case GeometryComponent::Type::Instance:
is_instance = true;
break;
case GEO_COMPONENT_TYPE_VOLUME:
is_instance = ob->type != OB_VOLUME;
case GeometryComponent::Type::Volume:
is_instance = object.type != OB_VOLUME;
break;
case GEO_COMPONENT_TYPE_CURVE:
is_instance = !ELEM(ob->type, OB_CURVES_LEGACY, OB_FONT);
case GeometryComponent::Type::Curve:
is_instance = !ELEM(object.type, OB_CURVES_LEGACY, OB_FONT);
break;
case GEO_COMPONENT_TYPE_EDIT:
case GeometryComponent::Type::Edit:
break;
}
if (is_instance) {
@ -745,4 +723,6 @@ bool BKE_object_has_geometry_set_instances(const Object *ob)
return false;
}
} // namespace blender::bke
/** \} */

View File

@ -65,9 +65,8 @@ GeometrySet object_get_evaluated_geometry_set(const Object &object)
}
void Instances::foreach_referenced_geometry(
blender::FunctionRef<void(const GeometrySet &geometry_set)> callback) const
FunctionRef<void(const GeometrySet &geometry_set)> callback) const
{
using namespace blender::bke;
for (const InstanceReference &reference : references_) {
switch (reference.type()) {
case InstanceReference::Type::Object: {
@ -99,8 +98,6 @@ void Instances::foreach_referenced_geometry(
void Instances::ensure_geometry_instances()
{
using namespace blender;
using namespace blender::bke;
VectorSet<InstanceReference> new_references;
new_references.reserve(references_.size());
for (const InstanceReference &reference : references_) {

View File

@ -67,21 +67,21 @@ void Instances::add_instance(const int instance_handle, const float4x4 &transfor
attributes_.reallocate(this->instances_num());
}
blender::Span<int> Instances::reference_handles() const
Span<int> Instances::reference_handles() const
{
return reference_handles_;
}
blender::MutableSpan<int> Instances::reference_handles()
MutableSpan<int> Instances::reference_handles()
{
return reference_handles_;
}
blender::MutableSpan<blender::float4x4> Instances::transforms()
MutableSpan<float4x4> Instances::transforms()
{
return transforms_;
}
blender::Span<blender::float4x4> Instances::transforms() const
Span<float4x4> Instances::transforms() const
{
return transforms_;
}
@ -102,7 +102,7 @@ int Instances::add_reference(const InstanceReference &reference)
return references_.index_of_or_add_as(reference);
}
blender::Span<InstanceReference> Instances::references() const
Span<InstanceReference> Instances::references() const
{
return references_;
}

View File

@ -670,6 +670,8 @@ bool BKE_mball_select_swap_multi_ex(Base **bases, int bases_len)
void BKE_mball_data_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
using namespace blender;
using namespace blender::bke;
BLI_assert(ob->type == OB_MBALL);
BKE_object_free_derived_caches(ob);
@ -705,11 +707,11 @@ void BKE_mball_data_update(Depsgraph *depsgraph, Scene *scene, Object *ob)
if (ob->runtime.bb == nullptr) {
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
}
blender::float3 min(std::numeric_limits<float>::max());
blender::float3 max(-std::numeric_limits<float>::max());
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 = blender::float3(0);
max = blender::float3(0);
min = float3(0);
max = float3(0);
}
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
};

View File

@ -571,7 +571,8 @@ void BKE_pointcloud_to_mesh(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/
BLI_assert(ob->type == OB_POINTCLOUD);
const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
const GeometrySet geometry = blender::bke::object_get_evaluated_geometry_set(*ob_eval);
const blender::bke::GeometrySet geometry = blender::bke::object_get_evaluated_geometry_set(
*ob_eval);
Mesh *mesh = BKE_mesh_add(bmain, ob->id.name + 2);
@ -688,7 +689,7 @@ static void curve_to_mesh_eval_ensure(Object &object)
static const Curves *get_evaluated_curves_from_object(const Object *object)
{
if (GeometrySet *geometry_set_eval = object->runtime.geometry_set_eval) {
if (blender::bke::GeometrySet *geometry_set_eval = object->runtime.geometry_set_eval) {
return geometry_set_eval->get_curves_for_read();
}
return nullptr;

View File

@ -3854,7 +3854,7 @@ int ntreeGetPanelIndex(const bNodeTree *ntree, const bNodePanel *panel)
return ntree->panels().first_index_try(const_cast<bNodePanel *>(panel));
}
bNodePanel *ntreeAddPanel(bNodeTree *ntree, const char *name, int flag)
bNodePanel *ntreeAddPanel(bNodeTree *ntree, const char *name)
{
bNodePanel **old_panels_array = ntree->panels_array;
const Span<const bNodePanel *> old_panels = ntree->panels();
@ -3867,7 +3867,7 @@ bNodePanel *ntreeAddPanel(bNodeTree *ntree, const char *name, int flag)
new_panels.data());
bNodePanel *new_panel = MEM_cnew<bNodePanel>(__func__);
*new_panel = {BLI_strdup(name), flag, ntree->next_panel_identifier++};
*new_panel = {BLI_strdup(name)};
new_panels[new_panels.size() - 1] = new_panel;
MEM_SAFE_FREE(old_panels_array);
@ -3877,7 +3877,7 @@ bNodePanel *ntreeAddPanel(bNodeTree *ntree, const char *name, int flag)
return new_panel;
}
bNodePanel *ntreeInsertPanel(bNodeTree *ntree, const char *name, int flag, int index)
bNodePanel *ntreeInsertPanel(bNodeTree *ntree, const char *name, int index)
{
if (!blender::IndexRange(ntree->panels().size() + 1).contains(index)) {
return nullptr;
@ -3899,7 +3899,7 @@ bNodePanel *ntreeInsertPanel(bNodeTree *ntree, const char *name, int flag, int i
new_panels.drop_front(index + 1).data());
bNodePanel *new_panel = MEM_cnew<bNodePanel>(__func__);
*new_panel = {BLI_strdup(name), flag, ntree->next_panel_identifier++};
*new_panel = {BLI_strdup(name)};
new_panels[index] = new_panel;
MEM_SAFE_FREE(old_panels_array);

View File

@ -506,11 +506,19 @@ static void ensure_topology_cache(const bNodeTree &ntree)
ToposortDirection::LeftToRight,
tree_runtime.toposort_left_to_right,
tree_runtime.has_available_link_cycle);
for (const int i : tree_runtime.toposort_left_to_right.index_range()) {
const bNode &node = *tree_runtime.toposort_left_to_right[i];
node.runtime->toposort_left_to_right_index = i;
}
},
[&]() {
bool dummy;
update_toposort(
ntree, ToposortDirection::RightToLeft, tree_runtime.toposort_right_to_left, dummy);
for (const int i : tree_runtime.toposort_right_to_left.index_range()) {
const bNode &node = *tree_runtime.toposort_right_to_left[i];
node.runtime->toposort_right_to_left_index = i;
}
},
[&]() { update_root_frames(ntree); },
[&]() { update_direct_frames_childrens(ntree); });

View File

@ -57,7 +57,7 @@ std::string node_tree_to_dot(const bNodeTree &tree, const bNodeTreeToDotOptions
dot_nodes.add_new(node, dot::NodeWithSocketsRef(dot_node, dot_node_with_sockets));
}
LISTBASE_FOREACH (const bNodeLink *, link, &tree.links) {
for (const bNodeLink *link : tree.all_links()) {
const dot::NodeWithSocketsRef &from_dot_node = dot_nodes.lookup(link->fromnode);
const dot::NodeWithSocketsRef &to_dot_node = dot_nodes.lookup(link->tonode);
const dot::NodePort from_dot_port = from_dot_node.output(link->fromsock->index());

View File

@ -107,10 +107,12 @@ static Vector<ZoneRelation> get_direct_zone_relations(
return zone_relations;
}
static void update_parent_zone_per_node(const Span<const bNode *> all_nodes,
const Span<std::unique_ptr<TreeZone>> all_zones,
const BitGroupVector<> &depend_on_input_flag_array,
Map<int, int> &r_parent_zone_by_node_id)
static void update_zone_per_node(const Span<const bNode *> all_nodes,
const Span<std::unique_ptr<TreeZone>> all_zones,
const BitGroupVector<> &depend_on_input_flag_array,
const Map<const bNode *, TreeZone *> &zone_by_inout_node,
Map<int, int> &r_zone_by_node_id,
Vector<const bNode *> &r_node_outside_zones)
{
for (const int node_i : all_nodes.index_range()) {
const bNode &node = *all_nodes[node_i];
@ -125,8 +127,37 @@ static void update_parent_zone_per_node(const Span<const bNode *> all_nodes,
parent_zone = zone;
}
});
if (parent_zone != nullptr) {
r_parent_zone_by_node_id.add(node.identifier, parent_zone->index);
if (parent_zone == nullptr) {
if (!zone_by_inout_node.contains(&node)) {
r_node_outside_zones.append(&node);
}
}
else {
r_zone_by_node_id.add(node.identifier, parent_zone->index);
}
}
for (const MapItem<const bNode *, TreeZone *> item : zone_by_inout_node.items()) {
r_zone_by_node_id.add_overwrite(item.key->identifier, item.value->index);
}
}
static void update_zone_border_links(const bNodeTree &tree, TreeZones &tree_zones)
{
for (const bNodeLink *link : tree.all_links()) {
if (!link->is_available()) {
continue;
}
if (link->is_muted()) {
continue;
}
TreeZone *from_zone = const_cast<TreeZone *>(tree_zones.get_zone_by_socket(*link->fromsock));
TreeZone *to_zone = const_cast<TreeZone *>(tree_zones.get_zone_by_socket(*link->tosock));
if (from_zone == to_zone) {
continue;
}
BLI_assert(from_zone == nullptr || from_zone->contains_zone_recursively(*to_zone));
for (TreeZone *zone = to_zone; zone != from_zone; zone = zone->parent_zone) {
zone->border_links.append(link);
}
}
}
@ -212,20 +243,34 @@ static std::unique_ptr<TreeZones> discover_tree_zones(const bNodeTree &tree)
update_zone_depths(*zone);
}
update_parent_zone_per_node(all_nodes,
tree_zones->zones,
depend_on_input_flag_array,
tree_zones->parent_zone_by_node_id);
for (std::unique_ptr<TreeZone> &zone : tree_zones->zones) {
if (zone->depth == 0) {
tree_zones->root_zones.append(zone.get());
}
}
update_zone_per_node(all_nodes,
tree_zones->zones,
depend_on_input_flag_array,
zone_by_inout_node,
tree_zones->zone_by_node_id,
tree_zones->nodes_outside_zones);
for (const int node_i : all_nodes.index_range()) {
const bNode *node = all_nodes[node_i];
const int parent_zone_i = tree_zones->parent_zone_by_node_id.lookup_default(node->identifier,
-1);
if (parent_zone_i != -1) {
tree_zones->zones[parent_zone_i]->child_nodes.append(node);
const int zone_i = tree_zones->zone_by_node_id.lookup_default(node->identifier, -1);
if (zone_i == -1) {
continue;
}
const TreeZone &zone = *tree_zones->zones[zone_i];
if (ELEM(node, zone.input_node, zone.output_node)) {
continue;
}
tree_zones->zones[zone_i]->child_nodes.append(node);
}
update_zone_border_links(tree, *tree_zones);
return tree_zones;
}
@ -239,11 +284,11 @@ const TreeZones *get_tree_zones(const bNodeTree &tree)
bool TreeZone::contains_node_recursively(const bNode &node) const
{
const TreeZones *zones = this->owner;
const int parent_zone_i = zones->parent_zone_by_node_id.lookup_default(node.identifier, -1);
if (parent_zone_i == -1) {
const int zone_i = zones->zone_by_node_id.lookup_default(node.identifier, -1);
if (zone_i == -1) {
return false;
}
for (const TreeZone *zone = zones->zones[parent_zone_i].get(); zone; zone = zone->parent_zone) {
for (const TreeZone *zone = zones->zones[zone_i].get(); zone; zone = zone->parent_zone) {
if (zone == this) {
return true;
}
@ -251,4 +296,35 @@ bool TreeZone::contains_node_recursively(const bNode &node) const
return false;
}
bool TreeZone::contains_zone_recursively(const TreeZone &other_zone) const
{
for (const TreeZone *zone = other_zone.parent_zone; zone; zone = zone->parent_zone) {
if (zone == this) {
return true;
}
}
return false;
}
const TreeZone *TreeZones::get_zone_by_socket(const bNodeSocket &socket) const
{
const bNode &node = socket.owner_node();
const int zone_i = this->zone_by_node_id.lookup_default(node.identifier, -1);
if (zone_i == -1) {
return nullptr;
}
const TreeZone &zone = *this->zones[zone_i];
if (zone.input_node == &node) {
if (socket.is_input()) {
return zone.parent_zone;
}
}
if (zone.output_node == &node) {
if (socket.is_output()) {
return zone.parent_zone;
}
}
return &zone;
}
} // namespace blender::bke::node_tree_zones

View File

@ -85,8 +85,8 @@
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_fcurve_driver.h"
#include "BKE_geometry_set.h"
#include "BKE_geometry_set.hh"
#include "BKE_geometry_set_instances.hh"
#include "BKE_global.h"
#include "BKE_gpencil_geom_legacy.h"
#include "BKE_gpencil_legacy.h"
@ -615,7 +615,7 @@ static void object_blend_write(BlendWriter *writer, ID *id, const void *id_addre
BLO_write_struct(writer, LightgroupMembership, ob->lightgroup);
}
if (ob->light_linking) {
BLO_write_struct(writer, LightgroupMembership, ob->light_linking);
BLO_write_struct(writer, LightLinking, ob->light_linking);
}
if (ob->lightprobe_cache) {
@ -1882,7 +1882,7 @@ void BKE_object_free_derived_caches(Object *ob)
}
if (ob->runtime.geometry_set_eval != nullptr) {
BKE_geometry_set_free(ob->runtime.geometry_set_eval);
delete ob->runtime.geometry_set_eval;
ob->runtime.geometry_set_eval = nullptr;
}
@ -2119,7 +2119,7 @@ int BKE_object_visibility(const Object *ob, const int dag_eval_mode)
visibility |= OB_VISIBLE_INSTANCES;
}
if (BKE_object_has_geometry_set_instances(ob)) {
if (blender::bke::object_has_geometry_set_instances(*ob)) {
visibility |= OB_VISIBLE_INSTANCES;
}
@ -4488,7 +4488,7 @@ Mesh *BKE_object_get_evaluated_mesh_no_subsurf(const Object *object)
{
/* First attempt to retrieve the evaluated mesh from the evaluated geometry set. Most
* object types either store it there or add a reference to it if it's owned elsewhere. */
GeometrySet *geometry_set_eval = object->runtime.geometry_set_eval;
blender::bke::GeometrySet *geometry_set_eval = object->runtime.geometry_set_eval;
if (geometry_set_eval) {
/* Some areas expect to be able to modify the evaluated mesh in limited ways. Theoretically
* this should be avoided, or at least protected with a lock, so a const mesh could be returned

View File

@ -38,8 +38,8 @@
#include "BKE_duplilist.h"
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
#include "BKE_geometry_set.h"
#include "BKE_geometry_set.hh"
#include "BKE_geometry_set_instances.hh"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_instances.hh"
@ -73,6 +73,7 @@ using blender::float3;
using blender::float4x4;
using blender::Span;
using blender::Vector;
using blender::bke::GeometrySet;
using blender::bke::InstanceReference;
using blender::bke::Instances;
namespace geo_log = blender::nodes::geo_eval_log;
@ -900,7 +901,9 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
}
}
if (!ELEM(ctx->object->type, OB_CURVES_LEGACY, OB_FONT, OB_CURVES) || geometry_set_is_instance) {
if (const CurveComponent *component = geometry_set.get_component_for_read<CurveComponent>()) {
if (const blender::bke::CurveComponent *component =
geometry_set.get_component_for_read<blender::bke::CurveComponent>())
{
if (use_new_curves_type) {
if (const Curves *curves = component->get_for_read()) {
make_dupli(ctx, ctx->object, &curves->id, parent_transform, component_index++);
@ -1724,7 +1727,7 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
}
if (ctx->object->runtime.geometry_set_eval != nullptr) {
if (BKE_object_has_geometry_set_instances(ctx->object)) {
if (blender::bke::object_has_geometry_set_instances(*ctx->object)) {
return &gen_dupli_geometry_set;
}
}
@ -1823,6 +1826,7 @@ static bool find_geonode_attribute_rgba(const DupliObject *dupli,
float r_value[4])
{
using namespace blender;
using namespace blender::bke;
/* Loop over layers from innermost to outermost. */
for (const int i : IndexRange(ARRAY_SIZE(dupli->instance_data))) {

View File

@ -329,7 +329,7 @@ PointCloud *BKE_pointcloud_copy_for_eval(const PointCloud *pointcloud_src)
static void pointcloud_evaluate_modifiers(Depsgraph *depsgraph,
Scene *scene,
Object *object,
GeometrySet &geometry_set)
blender::bke::GeometrySet &geometry_set)
{
/* Modifier evaluation modes. */
const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
@ -360,21 +360,22 @@ static void pointcloud_evaluate_modifiers(Depsgraph *depsgraph,
}
}
static PointCloud *take_pointcloud_ownership_from_geometry_set(GeometrySet &geometry_set)
static PointCloud *take_pointcloud_ownership_from_geometry_set(
blender::bke::GeometrySet &geometry_set)
{
if (!geometry_set.has<PointCloudComponent>()) {
if (!geometry_set.has<blender::bke::PointCloudComponent>()) {
return nullptr;
}
PointCloudComponent &pointcloud_component =
geometry_set.get_component_for_write<PointCloudComponent>();
blender::bke::PointCloudComponent &pointcloud_component =
geometry_set.get_component_for_write<blender::bke::PointCloudComponent>();
PointCloud *pointcloud = pointcloud_component.release();
if (pointcloud != nullptr) {
/* Add back, but as read-only non-owning component. */
pointcloud_component.replace(pointcloud, GeometryOwnershipType::ReadOnly);
pointcloud_component.replace(pointcloud, blender::bke::GeometryOwnershipType::ReadOnly);
}
else {
/* The component was empty, we can also remove it. */
geometry_set.remove<PointCloudComponent>();
geometry_set.remove<blender::bke::PointCloudComponent>();
}
return pointcloud;
}
@ -386,8 +387,8 @@ void BKE_pointcloud_data_update(Depsgraph *depsgraph, Scene *scene, Object *obje
/* Evaluate modifiers. */
PointCloud *pointcloud = static_cast<PointCloud *>(object->data);
GeometrySet geometry_set = GeometrySet::create_with_pointcloud(pointcloud,
GeometryOwnershipType::ReadOnly);
blender::bke::GeometrySet geometry_set = blender::bke::GeometrySet::create_with_pointcloud(
pointcloud, blender::bke::GeometryOwnershipType::ReadOnly);
pointcloud_evaluate_modifiers(depsgraph, scene, object, geometry_set);
PointCloud *pointcloud_eval = take_pointcloud_ownership_from_geometry_set(geometry_set);
@ -400,7 +401,7 @@ void BKE_pointcloud_data_update(Depsgraph *depsgraph, Scene *scene, Object *obje
/* Assign evaluated object. */
const bool eval_is_owned = pointcloud_eval != pointcloud;
BKE_object_eval_assign_data(object, &pointcloud_eval->id, eval_is_owned);
object->runtime.geometry_set_eval = new GeometrySet(std::move(geometry_set));
object->runtime.geometry_set_eval = new blender::bke::GeometrySet(std::move(geometry_set));
}
void PointCloud::tag_positions_changed()

View File

@ -1089,7 +1089,7 @@ static void volume_update_simplify_level(Volume *volume, const Depsgraph *depsgr
static void volume_evaluate_modifiers(Depsgraph *depsgraph,
Scene *scene,
Object *object,
GeometrySet &geometry_set)
blender::bke::GeometrySet &geometry_set)
{
/* Modifier evaluation modes. */
const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
@ -1142,20 +1142,20 @@ void BKE_volume_eval_geometry(Depsgraph *depsgraph, Volume *volume)
}
}
static Volume *take_volume_ownership_from_geometry_set(GeometrySet &geometry_set)
static Volume *take_volume_ownership_from_geometry_set(blender::bke::GeometrySet &geometry_set)
{
if (!geometry_set.has<VolumeComponent>()) {
if (!geometry_set.has<blender::bke::VolumeComponent>()) {
return nullptr;
}
VolumeComponent &volume_component = geometry_set.get_component_for_write<VolumeComponent>();
auto &volume_component = geometry_set.get_component_for_write<blender::bke::VolumeComponent>();
Volume *volume = volume_component.release();
if (volume != nullptr) {
/* Add back, but only as read-only non-owning component. */
volume_component.replace(volume, GeometryOwnershipType::ReadOnly);
volume_component.replace(volume, blender::bke::GeometryOwnershipType::ReadOnly);
}
else {
/* The component was empty, we can remove it. */
geometry_set.remove<VolumeComponent>();
geometry_set.remove<blender::bke::VolumeComponent>();
}
return volume;
}
@ -1167,8 +1167,8 @@ void BKE_volume_data_update(Depsgraph *depsgraph, Scene *scene, Object *object)
/* Evaluate modifiers. */
Volume *volume = (Volume *)object->data;
GeometrySet geometry_set;
geometry_set.replace_volume(volume, GeometryOwnershipType::ReadOnly);
blender::bke::GeometrySet geometry_set;
geometry_set.replace_volume(volume, blender::bke::GeometryOwnershipType::ReadOnly);
volume_evaluate_modifiers(depsgraph, scene, object, geometry_set);
Volume *volume_eval = take_volume_ownership_from_geometry_set(geometry_set);
@ -1181,7 +1181,7 @@ void BKE_volume_data_update(Depsgraph *depsgraph, Scene *scene, Object *object)
/* Assign evaluated object. */
const bool eval_is_owned = (volume != volume_eval);
BKE_object_eval_assign_data(object, &volume_eval->id, eval_is_owned);
object->runtime.geometry_set_eval = new GeometrySet(std::move(geometry_set));
object->runtime.geometry_set_eval = new blender::bke::GeometrySet(std::move(geometry_set));
}
void BKE_volume_grids_backup_restore(Volume *volume, VolumeGridVector *grids, const char *filepath)

View File

@ -99,10 +99,12 @@ set(SRC
intern/draw_manager_texture.c
intern/draw_pbvh.cc
intern/draw_pointcloud.cc
intern/draw_resource.cc
intern/draw_select_buffer.c
intern/draw_shader.cc
intern/draw_texture_pool.cc
intern/draw_view.c
intern/draw_view.cc
intern/draw_view_data.cc
intern/draw_volume.cc
engines/basic/basic_engine.c
@ -190,7 +192,6 @@ set(SRC
engines/gpencil/gpencil_draw_data.c
engines/gpencil/gpencil_engine.c
engines/gpencil/gpencil_engine.cc
engines/gpencil/gpencil_engine.h
engines/gpencil/gpencil_render.c
engines/gpencil/gpencil_shader.c
engines/gpencil/gpencil_shader.cc
@ -259,14 +260,12 @@ set(SRC
intern/draw_manager_text.h
intern/draw_pass.hh
intern/draw_pbvh.h
intern/draw_resource.cc
intern/draw_resource.hh
intern/draw_shader.h
intern/draw_shader_shared.h
intern/draw_state.h
intern/draw_subdivision.h
intern/draw_texture_pool.h
intern/draw_view.cc
intern/draw_view.h
intern/draw_view.hh
intern/draw_view_data.h
@ -302,6 +301,14 @@ set(SRC
engines/eevee_next/eevee_view.hh
engines/eevee_next/eevee_world.hh
engines/external/external_engine.h
engines/gpencil/gpencil_antialiasing.hh
engines/gpencil/gpencil_engine.h
engines/gpencil/gpencil_layer.hh
engines/gpencil/gpencil_light.hh
engines/gpencil/gpencil_material.hh
engines/gpencil/gpencil_object.hh
engines/gpencil/gpencil_shader.hh
engines/gpencil/gpencil_vfx.hh
engines/image/image_batches.hh
engines/image/image_buffer_cache.hh
engines/image/image_drawing_mode.hh
@ -316,18 +323,25 @@ set(SRC
engines/image/image_space_node.hh
engines/image/image_texture_info.hh
engines/image/image_usage.hh
engines/overlay/overlay_engine.h
engines/overlay/overlay_next_background.hh
engines/overlay/overlay_next_empty.hh
engines/overlay/overlay_next_grid.hh
engines/overlay/overlay_next_instance.hh
engines/overlay/overlay_next_metaball.hh
engines/overlay/overlay_next_prepass.hh
engines/overlay/overlay_next_private.hh
engines/overlay/overlay_private.hh
engines/select/select_defines.h
engines/select/select_engine.h
engines/select/select_instance.hh
engines/select/select_private.h
engines/workbench/workbench_defines.hh
engines/workbench/workbench_engine.h
engines/workbench/workbench_enums.hh
engines/workbench/workbench_private.h
engines/workbench/workbench_private.hh
engines/workbench/workbench_shader_shared.h
engines/select/select_engine.h
engines/select/select_private.h
engines/overlay/overlay_engine.h
engines/overlay/overlay_next_instance.hh
engines/overlay/overlay_next_private.hh
engines/overlay/overlay_private.hh
)
set(LIB

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_global.h"
#include "BLI_rect.h"

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_global.h"

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2021 Blender Foundation.
*/
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee
@ -209,7 +209,7 @@ float SubsurfaceModule::burley_eval(float d, float r)
/* Slide 33. */
float exp_r_3_d = expf(-r / (3.0f * d));
float exp_r_d = exp_r_3_d * exp_r_3_d * exp_r_3_d;
return (exp_r_d + exp_r_3_d) / (8.0f * (float)M_PI * d);
return (exp_r_d + exp_r_3_d) / (8.0f * float(M_PI) * d);
}
float SubsurfaceModule::burley_pdf(float d, float r)

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2021 Blender Foundation.
*/
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2021 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "eevee_defines.hh"
#include "gpu_shader_create_info.hh"

View File

@ -47,4 +47,4 @@ void OVERLAY_edit_grease_pencil_draw(OVERLAY_Data *vedata)
if (psl->edit_grease_pencil_ps) {
DRW_draw_pass(psl->edit_grease_pencil_ps);
}
}
}

View File

@ -168,8 +168,8 @@ void OVERLAY_viewer_attribute_cache_populate(OVERLAY_Data *vedata, Object *objec
DupliObject *dupli_object = DRW_object_get_dupli(object);
if (dupli_object->preview_instance_index >= 0) {
const InstancesComponent &instances =
*dupli_object->preview_base_geometry->get_component_for_read<InstancesComponent>();
const auto &instances = *dupli_object->preview_base_geometry
->get_component_for_read<blender::bke::InstancesComponent>();
if (instances.attributes()->contains(".viewer")) {
populate_cache_for_instance(*object, *pd, *dupli_object, opacity);
return;

View File

@ -1,7 +1,6 @@
/* SPDX-FileCopyrightText: 2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later
* */
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup draw

View File

@ -1319,4 +1319,4 @@ void create_suzanne(Main &bmain, Object &object, float4x4 matrix, const int fram
layer_fills.insert_frame(frame_number, frame_fills);
}
} // namespace blender::ed::greasepencil
} // namespace blender::ed::greasepencil

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

@ -108,7 +108,7 @@ AbstractTreeViewItem *AbstractTreeView::find_matching_child(
const AbstractTreeViewItem &lookup_item, const TreeViewOrItem &items)
{
for (const auto &iter_item : items.children_) {
if (lookup_item.matches_single(*iter_item)) {
if (lookup_item.matches(*iter_item)) {
/* We have a matching item! */
return iter_item.get();
}
@ -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(); });
}
@ -475,7 +489,7 @@ void TreeViewLayoutBuilder::build_row(AbstractTreeViewItem &item) const
}
uiLayout *row = uiLayoutRow(overlap, false);
/* Enable emboss for item mouse hover highlight. */
/* Enable emboss for mouse hover highlight. */
uiLayoutSetEmboss(row, UI_EMBOSS);
/* Every item gets one! Other buttons can be overlapped on top. */
item.add_treerow_button(block_);

View File

@ -29,10 +29,10 @@
# include "BKE_main.h"
# include "BKE_report.h"
# include "BLI_listbase.h"
# include "BLI_path_util.h"
# include "BLI_string.h"
# include "BLI_utildefines.h"
# include "BLI_vector.hh"
# include "BLT_translation.h"
@ -477,20 +477,6 @@ struct CacheFrame {
int framenr;
};
static int cmp_frame(const void *a, const void *b)
{
const CacheFrame *frame_a = static_cast<const CacheFrame *>(a);
const CacheFrame *frame_b = static_cast<const CacheFrame *>(b);
if (frame_a->framenr < frame_b->framenr) {
return -1;
}
if (frame_a->framenr > frame_b->framenr) {
return 1;
}
return 0;
}
static int get_sequence_len(const char *filepath, int *ofs)
{
int frame;
@ -524,8 +510,7 @@ static int get_sequence_len(const char *filepath, int *ofs)
const char *basename = BLI_path_basename(filepath);
const int len = strlen(basename) - (numdigit + strlen(ext));
ListBase frames{};
BLI_listbase_clear(&frames);
blender::Vector<CacheFrame> frames;
dirent *fname;
while ((fname = readdir(dir)) != nullptr) {
@ -538,34 +523,34 @@ static int get_sequence_len(const char *filepath, int *ofs)
continue;
}
CacheFrame *cache_frame = MEM_cnew<CacheFrame>("abc_frame");
CacheFrame cache_frame{};
BLI_path_frame_get(fname->d_name, &cache_frame->framenr, &numdigit);
BLI_path_frame_get(fname->d_name, &cache_frame.framenr, &numdigit);
BLI_addtail(&frames, cache_frame);
frames.append(cache_frame);
}
closedir(dir);
BLI_listbase_sort(&frames, cmp_frame);
std::sort(frames.begin(), frames.end(), [](const CacheFrame &a, const CacheFrame &b) {
return a.framenr < b.framenr;
});
CacheFrame *cache_frame = static_cast<CacheFrame *>(frames.first);
if (cache_frame != nullptr) {
int frame_curr = cache_frame->framenr;
(*ofs) = frame_curr;
while (cache_frame && (cache_frame->framenr == frame_curr)) {
frame_curr++;
cache_frame = cache_frame->next;
}
BLI_freelistN(&frames);
return frame_curr - (*ofs);
if (frames.is_empty()) {
return -1;
}
return 1;
int frame_curr = frames.first().framenr;
(*ofs) = frame_curr;
for (CacheFrame &cache_frame : frames) {
if (cache_frame.framenr != frame_curr) {
break;
}
frame_curr++;
}
return frame_curr - (*ofs);
}
/* ************************************************************************** */

View File

@ -56,8 +56,8 @@
#include "BKE_displist.h"
#include "BKE_duplilist.h"
#include "BKE_effect.h"
#include "BKE_geometry_set.h"
#include "BKE_geometry_set.hh"
#include "BKE_geometry_set_instances.hh"
#include "BKE_gpencil_curve_legacy.h"
#include "BKE_gpencil_geom_legacy.h"
#include "BKE_gpencil_legacy.h"
@ -2643,7 +2643,8 @@ static void make_object_duplilist_real(bContext *C,
Object *object_eval = DEG_get_evaluated_object(depsgraph, base->object);
if (!(base->object->transflag & OB_DUPLI) && !BKE_object_has_geometry_set_instances(object_eval))
if (!(base->object->transflag & OB_DUPLI) &&
!blender::bke::object_has_geometry_set_instances(*object_eval))
{
return;
}
@ -3244,7 +3245,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
GeometrySet geometry;
bke::GeometrySet geometry;
if (ob_eval->runtime.geometry_set_eval != nullptr) {
geometry = *ob_eval->runtime.geometry_set_eval;
}
@ -3265,8 +3266,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
newob = ob;
}
const CurveComponent &curve_component = *geometry.get_component_for_read<CurveComponent>();
const Curves *curves_eval = curve_component.get_for_read();
const Curves *curves_eval = geometry.get_curves_for_read();
Curves *new_curves = static_cast<Curves *>(BKE_id_new(bmain, ID_CV, newob->id.name + 2));
newob->data = new_curves;
@ -3543,7 +3543,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
GeometrySet geometry;
bke::GeometrySet geometry;
if (ob_eval->runtime.geometry_set_eval != nullptr) {
geometry = *ob_eval->runtime.geometry_set_eval;
}

View File

@ -51,6 +51,10 @@
#include "object_intern.h"
#include "WM_api.h"
#include "UI_interface.h"
namespace blender::ed::object::bake_simulation {
static bool calculate_to_frame_poll(bContext *C)
@ -252,10 +256,6 @@ static void bake_simulation_job_startjob(void *customdata,
if (md->type == eModifierType_Nodes) {
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
nmd->simulation_cache->ptr->reset();
if (StringRef(nmd->simulation_bake_directory).is_empty()) {
nmd->simulation_bake_directory = BLI_strdup(
bke::sim::get_default_modifier_bake_directory(*job.bmain, *object, *md).c_str());
}
char absolute_bake_dir[FILE_MAX];
STRNCPY(absolute_bake_dir, nmd->simulation_bake_directory);
BLI_path_abs(absolute_bake_dir, base_path);
@ -362,7 +362,7 @@ static void bake_simulation_job_endjob(void *customdata)
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, nullptr);
}
static int bake_simulation_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
static int bake_simulation_execute(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
Scene *scene = CTX_data_scene(C);
@ -405,6 +405,160 @@ static int bake_simulation_invoke(bContext *C, wmOperator *op, const wmEvent * /
return OPERATOR_RUNNING_MODAL;
}
struct PathStringHash {
uint64_t operator()(const StringRef s) const
{
/* Normalize the paths so we can compare them. */
DynamicStackBuffer<256> norm_buf(s.size() + 1, 8);
memcpy(norm_buf.buffer(), s.data(), s.size() + 1);
char *norm = static_cast<char *>(norm_buf.buffer());
BLI_path_slash_native(norm);
/* Strip ending slash. */
BLI_path_slash_rstrip(norm);
BLI_path_normalize(norm);
return get_default_hash(norm);
}
};
struct PathStringEquality {
bool operator()(const StringRef a, const StringRef b) const
{
return BLI_path_cmp_normalized(a.data(), b.data()) == 0;
}
};
static bool bake_directory_has_data(const StringRefNull absolute_bake_dir)
{
char meta_dir[FILE_MAX];
BLI_path_join(meta_dir, sizeof(meta_dir), absolute_bake_dir.c_str(), "meta");
char bdata_dir[FILE_MAX];
BLI_path_join(bdata_dir, sizeof(bdata_dir), absolute_bake_dir.c_str(), "bdata");
if (!BLI_is_dir(meta_dir) || !BLI_is_dir(bdata_dir)) {
return false;
}
return true;
}
static void bake_simulation_validate_paths(bContext *C,
wmOperator *op,
const Span<Object *> objects)
{
Main *bmain = CTX_data_main(C);
for (Object *object : objects) {
if (!BKE_id_is_editable(bmain, &object->id)) {
continue;
}
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
if (md->type != eModifierType_Nodes) {
continue;
}
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
if (StringRef(nmd->simulation_bake_directory).is_empty()) {
BKE_reportf(op->reports,
RPT_INFO,
"Bake directory of object %s, modifier %s is empty, setting default path",
object->id.name + 2,
md->name);
nmd->simulation_bake_directory = BLI_strdup(
bke::sim::get_default_modifier_bake_directory(*bmain, *object, *md).c_str());
}
}
}
}
/* Map for counting path references. */
using PathUsersMap = Map<std::string,
int,
default_inline_buffer_capacity(sizeof(std::string)),
DefaultProbingStrategy,
PathStringHash,
PathStringEquality>;
static PathUsersMap bake_simulation_get_path_users(bContext *C, const Span<Object *> objects)
{
Main *bmain = CTX_data_main(C);
PathUsersMap path_users;
for (const Object *object : objects) {
const char *base_path = ID_BLEND_PATH(bmain, &object->id);
LISTBASE_FOREACH (const ModifierData *, md, &object->modifiers) {
if (md->type != eModifierType_Nodes) {
continue;
}
const NodesModifierData *nmd = reinterpret_cast<const NodesModifierData *>(md);
if (StringRef(nmd->simulation_bake_directory).is_empty()) {
continue;
}
char absolute_bake_dir[FILE_MAX];
STRNCPY(absolute_bake_dir, nmd->simulation_bake_directory);
BLI_path_abs(absolute_bake_dir, base_path);
path_users.add_or_modify(
absolute_bake_dir, [](int *value) { *value = 1; }, [](int *value) { ++(*value); });
}
}
return path_users;
}
static int bake_simulation_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
Vector<Object *> objects;
if (RNA_boolean_get(op->ptr, "selected")) {
CTX_DATA_BEGIN (C, Object *, object, selected_objects) {
objects.append(object);
}
CTX_DATA_END;
}
else {
if (Object *object = CTX_data_active_object(C)) {
objects.append(object);
}
}
/* Set empty paths to default. */
bake_simulation_validate_paths(C, op, objects);
PathUsersMap path_users = bake_simulation_get_path_users(C, objects);
bool has_path_conflict = false;
bool has_existing_bake_data = false;
for (const auto &item : path_users.items()) {
/* Check if multiple caches are writing to the same bake directory. */
if (item.value > 1) {
BKE_reportf(op->reports,
RPT_ERROR,
"Path conflict: %d caches set to path %s",
item.value,
item.key.data());
has_path_conflict = true;
}
/* Check if path exists and contains bake data already. */
if (bake_directory_has_data(item.key.data())) {
has_existing_bake_data = true;
}
}
if (has_path_conflict) {
UI_popup_menu_reports(C, op->reports);
return OPERATOR_CANCELLED;
}
if (has_existing_bake_data) {
return WM_operator_confirm_message(C, op, "Overwrite existing bake data");
}
return bake_simulation_execute(C, op);
}
static int bake_simulation_modal(bContext *C, wmOperator * /*op*/, const wmEvent * /*event*/)
{
if (!WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_BAKE_SIMULATION_NODES)) {
@ -493,6 +647,7 @@ void OBJECT_OT_simulation_nodes_cache_bake(wmOperatorType *ot)
ot->description = "Bake simulations in geometry nodes modifiers";
ot->idname = __func__;
ot->exec = bake_simulation_execute;
ot->invoke = bake_simulation_invoke;
ot->modal = bake_simulation_modal;
ot->poll = bake_simulation_poll;

View File

@ -754,6 +754,7 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph,
const bool build_shapekey_layers,
ReportList *reports)
{
using namespace blender;
Mesh *me = ob_eval->runtime.data_orig ? reinterpret_cast<Mesh *>(ob_eval->runtime.data_orig) :
reinterpret_cast<Mesh *>(ob_eval->data);
const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md_eval->type));
@ -827,14 +828,14 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph,
}
if (mti->modifyGeometrySet) {
GeometrySet geometry_set = GeometrySet::create_with_mesh(mesh_temp,
GeometryOwnershipType::Owned);
bke::GeometrySet geometry_set = bke::GeometrySet::create_with_mesh(
mesh_temp, bke::GeometryOwnershipType::Owned);
mti->modifyGeometrySet(md_eval, &mectx, &geometry_set);
if (!geometry_set.has_mesh()) {
BKE_report(reports, RPT_ERROR, "Evaluated geometry from modifier does not contain a mesh");
return nullptr;
}
result = geometry_set.get_component_for_write<MeshComponent>().release();
result = geometry_set.get_component_for_write<bke::MeshComponent>().release();
}
else {
result = mti->modifyMesh(md_eval, &mectx, mesh_temp);
@ -954,6 +955,7 @@ static void remove_invalid_attribute_strings(Mesh &mesh)
static bool modifier_apply_obdata(
ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md_eval)
{
using namespace blender;
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md_eval->type);
if (mti->isDisabled && mti->isDisabled(scene, md_eval, false)) {
@ -1065,9 +1067,9 @@ static bool modifier_apply_obdata(
}
/* Create a temporary geometry set and component. */
GeometrySet geometry_set;
geometry_set.get_component_for_write<CurveComponent>().replace(
&curves, GeometryOwnershipType::ReadOnly);
bke::GeometrySet geometry_set;
geometry_set.get_component_for_write<bke::CurveComponent>().replace(
&curves, bke::GeometryOwnershipType::ReadOnly);
ModifierEvalContext mectx = {depsgraph, ob, ModifierApplyFlag(0)};
mti->modifyGeometrySet(md_eval, &mectx, &geometry_set);
@ -1093,9 +1095,9 @@ static bool modifier_apply_obdata(
}
/* Create a temporary geometry set and component. */
GeometrySet geometry_set;
geometry_set.get_component_for_write<PointCloudComponent>().replace(
&points, GeometryOwnershipType::ReadOnly);
bke::GeometrySet geometry_set;
geometry_set.get_component_for_write<bke::PointCloudComponent>().replace(
&points, bke::GeometryOwnershipType::ReadOnly);
ModifierEvalContext mectx = {depsgraph, ob, ModifierApplyFlag(0)};
mti->modifyGeometrySet(md_eval, &mectx, &geometry_set);
@ -1105,7 +1107,7 @@ static bool modifier_apply_obdata(
return false;
}
PointCloud *pointcloud_eval =
geometry_set.get_component_for_write<PointCloudComponent>().release();
geometry_set.get_component_for_write<bke::PointCloudComponent>().release();
/* Anonymous attributes shouldn't be available on the applied geometry. */
pointcloud_eval->attributes_for_write().remove_anonymous();

View File

@ -412,7 +412,7 @@ static void nla_main_region_message_subscribe(const wmRegionMessageSubscribePara
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceNLA, area->spacedata.first, &ptr);
wmMsgSubscribeValue msg_sub_value_region_tag_redraw;
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {};
msg_sub_value_region_tag_redraw.owner = region;
msg_sub_value_region_tag_redraw.user_data = region;
msg_sub_value_region_tag_redraw.notify = ED_region_do_msg_notify_tag_redraw;
@ -488,7 +488,7 @@ static void nla_channel_region_message_subscribe(const wmRegionMessageSubscribeP
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceNLA, area->spacedata.first, &ptr);
wmMsgSubscribeValue msg_sub_value_region_tag_redraw;
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {};
msg_sub_value_region_tag_redraw.owner = region;
msg_sub_value_region_tag_redraw.user_data = region;
msg_sub_value_region_tag_redraw.notify = ED_region_do_msg_notify_tag_redraw;

View File

@ -938,7 +938,7 @@ static void create_inspection_string_for_field_info(const bNodeSocket &socket,
static void create_inspection_string_for_geometry_info(const geo_log::GeometryInfoLog &value_log,
std::stringstream &ss)
{
Span<GeometryComponentType> component_types = value_log.component_types;
Span<bke::GeometryComponent::Type> component_types = value_log.component_types;
if (component_types.is_empty()) {
ss << TIP_("Empty Geometry");
return;
@ -951,9 +951,9 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn
};
ss << TIP_("Geometry:") << "\n";
for (GeometryComponentType type : component_types) {
for (bke::GeometryComponent::Type type : component_types) {
switch (type) {
case GEO_COMPONENT_TYPE_MESH: {
case bke::GeometryComponent::Type::Mesh: {
const geo_log::GeometryInfoLog::MeshInfo &mesh_info = *value_log.mesh_info;
char line[256];
SNPRINTF(line,
@ -964,7 +964,7 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn
ss << line;
break;
}
case GEO_COMPONENT_TYPE_POINT_CLOUD: {
case bke::GeometryComponent::Type::PointCloud: {
const geo_log::GeometryInfoLog::PointCloudInfo &pointcloud_info =
*value_log.pointcloud_info;
char line[256];
@ -974,7 +974,7 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn
ss << line;
break;
}
case GEO_COMPONENT_TYPE_CURVE: {
case bke::GeometryComponent::Type::Curve: {
const geo_log::GeometryInfoLog::CurveInfo &curve_info = *value_log.curve_info;
char line[256];
SNPRINTF(line,
@ -984,7 +984,7 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn
ss << line;
break;
}
case GEO_COMPONENT_TYPE_INSTANCES: {
case bke::GeometryComponent::Type::Instance: {
const geo_log::GeometryInfoLog::InstancesInfo &instances_info = *value_log.instances_info;
char line[256];
SNPRINTF(
@ -992,11 +992,11 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn
ss << line;
break;
}
case GEO_COMPONENT_TYPE_VOLUME: {
case bke::GeometryComponent::Type::Volume: {
ss << TIP_("\u2022 Volume");
break;
}
case GEO_COMPONENT_TYPE_EDIT: {
case bke::GeometryComponent::Type::Edit: {
if (value_log.edit_data_info.has_value()) {
const geo_log::GeometryInfoLog::EditDataInfo &edit_info = *value_log.edit_data_info;
char line[256];
@ -1029,36 +1029,36 @@ static void create_inspection_string_for_geometry_socket(std::stringstream &ss,
ss << ".\n\n";
}
Span<GeometryComponentType> supported_types = socket_decl->supported_types();
Span<bke::GeometryComponent::Type> supported_types = socket_decl->supported_types();
if (supported_types.is_empty()) {
ss << TIP_("Supported: All Types");
return;
}
ss << TIP_("Supported: ");
for (GeometryComponentType type : supported_types) {
for (bke::GeometryComponent::Type type : supported_types) {
switch (type) {
case GEO_COMPONENT_TYPE_MESH: {
case bke::GeometryComponent::Type::Mesh: {
ss << TIP_("Mesh");
break;
}
case GEO_COMPONENT_TYPE_POINT_CLOUD: {
case bke::GeometryComponent::Type::PointCloud: {
ss << TIP_("Point Cloud");
break;
}
case GEO_COMPONENT_TYPE_CURVE: {
case bke::GeometryComponent::Type::Curve: {
ss << TIP_("Curve");
break;
}
case GEO_COMPONENT_TYPE_INSTANCES: {
case bke::GeometryComponent::Type::Instance: {
ss << TIP_("Instances");
break;
}
case GEO_COMPONENT_TYPE_VOLUME: {
case bke::GeometryComponent::Type::Volume: {
ss << CTX_TIP_(BLT_I18NCONTEXT_ID_ID, "Volume");
break;
}
case GEO_COMPONENT_TYPE_EDIT: {
case bke::GeometryComponent::Type::Edit: {
break;
}
}
@ -3100,7 +3100,7 @@ static void find_bounds_by_zone_recursive(const SpaceNode &snode,
if (link.fromnode == nullptr) {
continue;
}
if (zone.contains_node_recursively(*link.fromnode) || zone.input_node == link.fromnode) {
if (zone.contains_node_recursively(*link.fromnode) && zone.output_node != link.fromnode) {
const float2 pos = node_link_bezier_points_dragged(snode, link)[3];
rctf rect;
BLI_rctf_init_pt_radius(&rect, pos, node_padding);
@ -3246,14 +3246,14 @@ static void node_draw_nodetree(const bContext &C,
GPU_blend(GPU_BLEND_ALPHA);
nodelink_batch_start(snode);
LISTBASE_FOREACH (const bNodeLink *, link, &ntree.links) {
for (const bNodeLink *link : ntree.all_links()) {
if (!nodeLinkIsHidden(link) && !bke::nodeLinkIsSelected(link)) {
node_draw_link(C, region.v2d, snode, *link, false);
}
}
/* Draw selected node links after the unselected ones, so they are shown on top. */
LISTBASE_FOREACH (const bNodeLink *, link, &ntree.links) {
for (const bNodeLink *link : ntree.all_links()) {
if (!nodeLinkIsHidden(link) && bke::nodeLinkIsSelected(link)) {
node_draw_link(C, region.v2d, snode, *link, true);
}

View File

@ -1624,7 +1624,7 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator * /*op*/)
* This way, when pasted strips are renamed, curves are renamed with them. Finally, restore
* original curves from backup.
*/
SeqAnimationBackup animation_backup = {0};
SeqAnimationBackup animation_backup = {{nullptr}};
SEQ_animation_backup_original(scene, &animation_backup);
Sequence *seq = static_cast<Sequence *>(duplicated_strips.first);
@ -2599,7 +2599,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
* curves from backup.
*/
SeqAnimationBackup animation_backup = {0};
SeqAnimationBackup animation_backup = {{nullptr}};
SEQ_animation_backup_original(scene, &animation_backup);
sequencer_paste_animation(C);

Some files were not shown because too many files have changed in this diff Show More