diff options
author | Hans Goudey <h.goudey@me.com> | 2022-06-04 13:55:19 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-06-04 13:55:19 +0300 |
commit | 735cf5069c8e36b28f747b5b1a8fffe7505b0aa2 (patch) | |
tree | b759966f323167c29cbb2d76b032f0cf857b10ce /source/blender | |
parent | 5cbaf55fe60950c7e936f728bffbb2c68c80763e (diff) | |
parent | 9531eb24b3172d83660649cc0936c05f66aff79b (diff) |
Merge branch 'master' into refactor-mesh-hide-generic
Diffstat (limited to 'source/blender')
435 files changed, 5498 insertions, 4263 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 59f0c86684d..4274ca97fd1 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -68,8 +68,8 @@ struct Object; struct Scene; /* - * NOTE: all mface interfaces now officially operate on tessellated data. - * Also, the mface origindex layer indexes mpolys, not mfaces. + * NOTE: all #MFace interfaces now officially operate on tessellated data. + * Also, the #MFace orig-index layer indexes #MPoly, not #MFace. */ /* keep in sync with MFace/MPoly types */ diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h index ebc95c4247c..78edb6b95ed 100644 --- a/source/blender/blenkernel/BKE_attribute.h +++ b/source/blender/blenkernel/BKE_attribute.h @@ -22,7 +22,7 @@ struct ID; struct ReportList; /** #Attribute.domain */ -typedef enum AttributeDomain { +typedef enum eAttrDomain { ATTR_DOMAIN_AUTO = -1, /* Use for nodes to choose automatically based on other data. */ ATTR_DOMAIN_POINT = 0, /* Mesh, Curve or Point Cloud Point */ ATTR_DOMAIN_EDGE = 1, /* Mesh Edge */ @@ -30,21 +30,23 @@ typedef enum AttributeDomain { ATTR_DOMAIN_CORNER = 3, /* Mesh Corner */ ATTR_DOMAIN_CURVE = 4, /* A single curve in a larger curve data-block */ ATTR_DOMAIN_INSTANCE = 5, /* Instance */ -} AttributeDomain; +} eAttrDomain; #define ATTR_DOMAIN_NUM 6 -typedef enum AttributeDomainMask { +typedef enum eAttrDomainMask { ATTR_DOMAIN_MASK_POINT = (1 << 0), ATTR_DOMAIN_MASK_EDGE = (1 << 1), ATTR_DOMAIN_MASK_FACE = (1 << 2), ATTR_DOMAIN_MASK_CORNER = (1 << 3), ATTR_DOMAIN_MASK_CURVE = (1 << 4), ATTR_DOMAIN_MASK_ALL = (1 << 5) - 1 -} AttributeDomainMask; +} eAttrDomainMask; + +#define ATTR_DOMAIN_AS_MASK(domain) ((eAttrDomainMask)((1 << (int)(domain)))) /* All domains that support color attributes. */ #define ATTR_DOMAIN_MASK_COLOR \ - ((AttributeDomainMask)((ATTR_DOMAIN_MASK_POINT | ATTR_DOMAIN_MASK_CORNER))) + ((eAttrDomainMask)((ATTR_DOMAIN_MASK_POINT | ATTR_DOMAIN_MASK_CORNER))) /* Attributes. */ @@ -55,7 +57,7 @@ bool BKE_attribute_allow_procedural_access(const char *attribute_name); * Create a new attribute layer. */ struct CustomDataLayer *BKE_id_attribute_new( - struct ID *id, const char *name, int type, AttributeDomain domain, struct ReportList *reports); + struct ID *id, const char *name, int type, eAttrDomain domain, struct ReportList *reports); bool BKE_id_attribute_remove(struct ID *id, struct CustomDataLayer *layer, struct ReportList *reports); @@ -63,9 +65,14 @@ bool BKE_id_attribute_remove(struct ID *id, struct CustomDataLayer *BKE_id_attribute_find(const struct ID *id, const char *name, int type, - AttributeDomain domain); + eAttrDomain domain); + +struct CustomDataLayer *BKE_id_attribute_search(const struct ID *id, + const char *name, + eCustomDataMask type, + eAttrDomainMask domain_mask); -AttributeDomain BKE_id_attribute_domain(const struct ID *id, const struct CustomDataLayer *layer); +eAttrDomain BKE_id_attribute_domain(const struct ID *id, const struct CustomDataLayer *layer); int BKE_id_attribute_data_length(struct ID *id, struct CustomDataLayer *layer); bool BKE_id_attribute_required(struct ID *id, struct CustomDataLayer *layer); bool BKE_id_attribute_rename(struct ID *id, @@ -74,8 +81,8 @@ bool BKE_id_attribute_rename(struct ID *id, struct ReportList *reports); int BKE_id_attributes_length(const struct ID *id, - AttributeDomainMask domain_mask, - CustomDataMask mask); + eAttrDomainMask domain_mask, + eCustomDataMask mask); struct CustomDataLayer *BKE_id_attributes_active_get(struct ID *id); void BKE_id_attributes_active_set(struct ID *id, struct CustomDataLayer *layer); @@ -84,24 +91,24 @@ int *BKE_id_attributes_active_index_p(struct ID *id); CustomData *BKE_id_attributes_iterator_next_domain(struct ID *id, struct CustomDataLayer *layers); CustomDataLayer *BKE_id_attribute_from_index(struct ID *id, int lookup_index, - AttributeDomainMask domain_mask, - CustomDataMask layer_mask); + eAttrDomainMask domain_mask, + eCustomDataMask layer_mask); /** Layer is allowed to be nullptr; if so -1 (layer not found) will be returned. */ int BKE_id_attribute_to_index(const struct ID *id, const CustomDataLayer *layer, - AttributeDomainMask domain_mask, - CustomDataMask layer_mask); + eAttrDomainMask domain_mask, + eCustomDataMask layer_mask); struct CustomDataLayer *BKE_id_attribute_subset_active_get(const struct ID *id, int active_flag, - AttributeDomainMask domain_mask, - CustomDataMask mask); + eAttrDomainMask domain_mask, + eCustomDataMask mask); void BKE_id_attribute_subset_active_set(struct ID *id, struct CustomDataLayer *layer, int active_flag, - AttributeDomainMask domain_mask, - CustomDataMask mask); + eAttrDomainMask domain_mask, + eCustomDataMask mask); /** * Sets up a temporary ID with arbitrary CustomData domains. `r_id` will diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh index c8c7c4c6808..fef91d6f75d 100644 --- a/source/blender/blenkernel/BKE_attribute_access.hh +++ b/source/blender/blenkernel/BKE_attribute_access.hh @@ -32,7 +32,7 @@ * extremely important for writing coherent bug-free code. When an attribute is retrieved with * write access, via #WriteAttributeLookup or #OutputAttribute, the geometry component must be * tagged to clear caches that depend on the changed data. - * 2. Domain interpolation: When retrieving an attribute, a domain (#AttributeDomain) can be + * 2. Domain interpolation: When retrieving an attribute, a domain (#eAttrDomain) can be * provided. If the attribute is stored on a different domain and conversion is possible, a * version of the data interpolated to the requested domain will be provided. These conversions * are implemented in each #GeometryComponent by `attribute_try_adapt_domain_impl`. @@ -88,8 +88,8 @@ extern const char *no_procedural_access_message; * stored (uv map, vertex group, ...). */ struct AttributeMetaData { - AttributeDomain domain; - CustomDataType data_type; + eAttrDomain domain; + eCustomDataType data_type; constexpr friend bool operator==(AttributeMetaData a, AttributeMetaData b) { @@ -98,8 +98,8 @@ struct AttributeMetaData { }; struct AttributeKind { - AttributeDomain domain; - CustomDataType data_type; + eAttrDomain domain; + eCustomDataType data_type; }; /** @@ -167,12 +167,12 @@ using AttributeForeachCallback = blender::FunctionRef<bool( namespace blender::bke { -CustomDataType attribute_data_type_highest_complexity(Span<CustomDataType> data_types); +eCustomDataType attribute_data_type_highest_complexity(Span<eCustomDataType> data_types); /** * Domains with a higher "information density" have a higher priority, * in order to choose a domain that will not lose data through domain conversion. */ -AttributeDomain attribute_domain_highest_priority(Span<AttributeDomain> domains); +eAttrDomain attribute_domain_highest_priority(Span<eAttrDomain> domains); /** * Used when looking up a "plain attribute" based on a name for reading from it. @@ -181,7 +181,7 @@ struct ReadAttributeLookup { /* The virtual array that is used to read from this attribute. */ GVArray varray; /* Domain the attribute lives on in the geometry. */ - AttributeDomain domain; + eAttrDomain domain; /* Convenience function to check if the attribute has been found. */ operator bool() const @@ -197,7 +197,7 @@ struct WriteAttributeLookup { /** The virtual array that is used to read from and write to the attribute. */ GVMutableArray varray; /** Domain the attributes lives on in the geometry component. */ - AttributeDomain domain; + eAttrDomain domain; /** * Call this after changing the attribute to invalidate caches that depend on this attribute. * \note Do not call this after the component the attribute is from has been destructed. @@ -232,7 +232,7 @@ class OutputAttribute { private: GVMutableArray varray_; - AttributeDomain domain_ = ATTR_DOMAIN_AUTO; + eAttrDomain domain_ = ATTR_DOMAIN_AUTO; SaveFn save_; std::unique_ptr<GVMutableArray_GSpan> optional_span_varray_; bool ignore_old_values_ = false; @@ -241,10 +241,7 @@ class OutputAttribute { public: OutputAttribute(); OutputAttribute(OutputAttribute &&other); - OutputAttribute(GVMutableArray varray, - AttributeDomain domain, - SaveFn save, - bool ignore_old_values); + OutputAttribute(GVMutableArray varray, eAttrDomain domain, SaveFn save, bool ignore_old_values); ~OutputAttribute(); @@ -253,9 +250,9 @@ class OutputAttribute { GVMutableArray &operator*(); GVMutableArray *operator->(); GVMutableArray &varray(); - AttributeDomain domain() const; + eAttrDomain domain() const; const CPPType &cpp_type() const; - CustomDataType custom_data_type() const; + eCustomDataType custom_data_type() const; GMutableSpan as_span(); template<typename T> MutableSpan<T> as_span(); @@ -313,7 +310,7 @@ template<typename T> class OutputAttribute_Typed { return varray_; } - AttributeDomain domain() const + eAttrDomain domain() const { return attribute_.domain(); } @@ -323,7 +320,7 @@ template<typename T> class OutputAttribute_Typed { return CPPType::get<T>(); } - CustomDataType custom_data_type() const + eCustomDataType custom_data_type() const { return cpp_type_to_custom_data_type(this->cpp_type()); } @@ -379,23 +376,21 @@ class CustomDataAttributes { * value for the type will be used. */ blender::GVArray get_for_read(const AttributeIDRef &attribute_id, - const CustomDataType data_type, + eCustomDataType data_type, const void *default_value) const; template<typename T> blender::VArray<T> get_for_read(const AttributeIDRef &attribute_id, const T &default_value) const { const blender::CPPType &cpp_type = blender::CPPType::get<T>(); - const CustomDataType type = blender::bke::cpp_type_to_custom_data_type(cpp_type); + const eCustomDataType type = blender::bke::cpp_type_to_custom_data_type(cpp_type); GVArray varray = this->get_for_read(attribute_id, type, &default_value); return varray.typed<T>(); } std::optional<blender::GMutableSpan> get_for_write(const AttributeIDRef &attribute_id); - bool create(const AttributeIDRef &attribute_id, const CustomDataType data_type); - bool create_by_move(const AttributeIDRef &attribute_id, - const CustomDataType data_type, - void *buffer); + bool create(const AttributeIDRef &attribute_id, eCustomDataType data_type); + bool create_by_move(const AttributeIDRef &attribute_id, eCustomDataType data_type, void *buffer); bool remove(const AttributeIDRef &attribute_id); /** @@ -403,7 +398,7 @@ class CustomDataAttributes { */ void reorder(Span<AttributeIDRef> new_order); - bool foreach_attribute(const AttributeForeachCallback callback, AttributeDomain domain) const; + bool foreach_attribute(const AttributeForeachCallback callback, eAttrDomain domain) const; }; /* -------------------------------------------------------------------- */ @@ -491,7 +486,7 @@ inline OutputAttribute::OutputAttribute() = default; inline OutputAttribute::OutputAttribute(OutputAttribute &&other) = default; inline OutputAttribute::OutputAttribute(GVMutableArray varray, - AttributeDomain domain, + eAttrDomain domain, SaveFn save, const bool ignore_old_values) : varray_(std::move(varray)), @@ -521,7 +516,7 @@ inline GVMutableArray &OutputAttribute::varray() return varray_; } -inline AttributeDomain OutputAttribute::domain() const +inline eAttrDomain OutputAttribute::domain() const { return domain_; } @@ -531,7 +526,7 @@ inline const CPPType &OutputAttribute::cpp_type() const return varray_.type(); } -inline CustomDataType OutputAttribute::custom_data_type() const +inline eCustomDataType OutputAttribute::custom_data_type() const { return cpp_type_to_custom_data_type(this->cpp_type()); } diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh index 3d194ba77dc..01c2ef988f2 100644 --- a/source/blender/blenkernel/BKE_attribute_math.hh +++ b/source/blender/blenkernel/BKE_attribute_math.hh @@ -39,7 +39,7 @@ inline void convert_to_static_type(const CPPType &cpp_type, const Func &func) } template<typename Func> -inline void convert_to_static_type(const CustomDataType data_type, const Func &func) +inline void convert_to_static_type(const eCustomDataType data_type, const Func &func) { const CPPType &cpp_type = *bke::custom_data_type_to_cpp_type(data_type); convert_to_static_type(cpp_type, func); diff --git a/source/blender/blenkernel/BKE_callbacks.h b/source/blender/blenkernel/BKE_callbacks.h index 8b2af96a063..8c65214c78e 100644 --- a/source/blender/blenkernel/BKE_callbacks.h +++ b/source/blender/blenkernel/BKE_callbacks.h @@ -97,6 +97,12 @@ typedef enum { BKE_CB_EVT_XR_SESSION_START_PRE, BKE_CB_EVT_ANNOTATION_PRE, BKE_CB_EVT_ANNOTATION_POST, + BKE_CB_EVT_OBJECT_BAKE_PRE, + BKE_CB_EVT_OBJECT_BAKE_COMPLETE, + BKE_CB_EVT_OBJECT_BAKE_CANCEL, + BKE_CB_EVT_COMPOSITE_PRE, + BKE_CB_EVT_COMPOSITE_POST, + BKE_CB_EVT_COMPOSITE_CANCEL, BKE_CB_EVT_TOT, } eCbEvent; diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h index b7aa1c09e04..40df7acd066 100644 --- a/source/blender/blenkernel/BKE_camera.h +++ b/source/blender/blenkernel/BKE_camera.h @@ -171,7 +171,7 @@ struct CameraBGImage *BKE_camera_background_image_new(struct Camera *cam); * `BKE_lib_id.h`. */ struct CameraBGImage *BKE_camera_background_image_copy(struct CameraBGImage *bgpic_src, - const int copy_flag); + const int copy_flag); void BKE_camera_background_image_remove(struct Camera *cam, struct CameraBGImage *bgpic); void BKE_camera_background_image_clear(struct Camera *cam); diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h index a3bbcc8687a..41d369ae9b2 100644 --- a/source/blender/blenkernel/BKE_collection.h +++ b/source/blender/blenkernel/BKE_collection.h @@ -115,6 +115,18 @@ bool BKE_collection_is_empty(const struct Collection *collection); bool BKE_collection_object_add(struct Main *bmain, struct Collection *collection, struct Object *ob); + +/** + * Add object to given collection, similar to #BKE_collection_object_add. + * + * However, it additionnally ensures that the selected collection is also part of the given + * `view_layer`, if non-NULL. Otherwise, the object is not added to any collection. + */ +bool BKE_collection_viewlayer_object_add(struct Main *bmain, + const struct ViewLayer *view_layer, + struct Collection *collection, + struct Object *ob); + /** * Same as #BKE_collection_object_add, but unconditionally adds the object to the given collection. * diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index ce1f4c2b98c..737b05fee0c 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -307,6 +307,25 @@ void BKE_constraint_target_matrix_get(struct Depsgraph *depsgraph, void *ownerdata, float mat[4][4], float ctime); + +/** + * Retrieves the list of all constraint targets, including the custom space target. + * Must be followed by a call to BKE_constraint_targets_flush to free memory. + * + * \param r_targets Pointer to the list to be initialized with target data. + * \returns the number of targets stored in the list. + */ +int BKE_constraint_targets_get(struct bConstraint *con, struct ListBase *r_targets); + +/** + * Copies changed data from the list produced by BKE_constraint_targets_get back to the constraint + * data structures and frees memory. + * + * \param targets List of targets filled by BKE_constraint_targets_get. + * \param no_copy Only free memory without copying changes (read-only mode). + */ +void BKE_constraint_targets_flush(struct bConstraint *con, struct ListBase *targets, bool no_copy); + /** * Get the list of targets required for solving a constraint. */ diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index f441203d9d6..b7068720469 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -222,9 +222,10 @@ void CTX_wm_operator_poll_msg_clear(struct bContext *C); /* Data Context * - * - listbases consist of CollectionPointerLink items and must be - * freed with BLI_freelistN! - * - the dir listbase consists of LinkData items */ + * - #ListBase consists of #CollectionPointerLink items and must be + * freed with #BLI_freelistN! + * - The dir #ListBase consists of #LinkData items. + */ /* data type, needed so we can tell between a NULL pointer and an empty list */ enum { diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index cc056dab248..168b17bad30 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -281,6 +281,11 @@ class CurvesGeometry : public ::CurvesGeometry { Span<float2> surface_triangle_coords() const; MutableSpan<float2> surface_triangle_coords_for_write(); + VArray<float> selection_point_float() const; + MutableSpan<float> selection_point_float_for_write(); + VArray<float> selection_curve_float() const; + MutableSpan<float> selection_curve_float_for_write(); + /** * Calculate the largest and smallest position values, only including control points * (rather than evaluated points). The existing values of `min` and `max` are taken into account. @@ -405,7 +410,12 @@ class CurvesGeometry : public ::CurvesGeometry { * Attributes. */ - GVArray adapt_domain(const GVArray &varray, AttributeDomain from, AttributeDomain to) const; + GVArray adapt_domain(const GVArray &varray, eAttrDomain from, eAttrDomain to) const; + template<typename T> + VArray<T> adapt_domain(const VArray<T> &varray, eAttrDomain from, eAttrDomain to) const + { + return this->adapt_domain(GVArray(varray), from, to).typed<T>(); + } }; namespace curves { diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 64c49830dc5..993ab476830 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -28,7 +28,7 @@ struct BlendWriter; struct CustomData; struct CustomData_MeshMasks; struct ID; -typedef uint64_t CustomDataMask; +typedef uint64_t eCustomDataMask; /* A data type large enough to hold 1 element from any custom-data layer type. */ typedef struct { @@ -63,7 +63,7 @@ typedef enum eCDAllocType { CD_DUPLICATE = 4, } eCDAllocType; -#define CD_TYPE_AS_MASK(_type) (CustomDataMask)((CustomDataMask)1 << (CustomDataMask)(_type)) +#define CD_TYPE_AS_MASK(_type) (eCustomDataMask)((eCustomDataMask)1 << (eCustomDataMask)(_type)) void customData_mask_layers__print(const struct CustomData_MeshMasks *mask); @@ -137,7 +137,7 @@ void CustomData_data_add(int type, void *data1, const void *data2); */ void CustomData_copy(const struct CustomData *source, struct CustomData *dest, - CustomDataMask mask, + eCustomDataMask mask, eCDAllocType alloctype, int totelem); @@ -150,7 +150,7 @@ void CustomData_update_typemap(struct CustomData *data); */ bool CustomData_merge(const struct CustomData *source, struct CustomData *dest, - CustomDataMask mask, + eCustomDataMask mask, eCDAllocType alloctype, int totelem); @@ -170,7 +170,7 @@ void CustomData_realloc(struct CustomData *data, int totelem); */ bool CustomData_bmesh_merge(const struct CustomData *source, struct CustomData *dest, - CustomDataMask mask, + eCustomDataMask mask, eCDAllocType alloctype, struct BMesh *bm, char htype); @@ -188,7 +188,7 @@ void CustomData_free(struct CustomData *data, int totelem); /** * Same as above, but only frees layers which matches the given mask. */ -void CustomData_free_typemask(struct CustomData *data, int totelem, CustomDataMask mask); +void CustomData_free_typemask(struct CustomData *data, int totelem, eCustomDataMask mask); /** * Frees all layers with #CD_FLAG_TEMPORARY. @@ -248,7 +248,7 @@ bool CustomData_has_layer(const struct CustomData *data, int type); * Returns the number of layers with this type. */ int CustomData_number_of_layers(const struct CustomData *data, int type); -int CustomData_number_of_layers_typemask(const struct CustomData *data, CustomDataMask mask); +int CustomData_number_of_layers_typemask(const struct CustomData *data, eCustomDataMask mask); /** * Duplicate data of a layer with flag NOFREE, and remove that flag. @@ -276,7 +276,7 @@ void CustomData_duplicate_referenced_layers(CustomData *data, int totelem); * Set the #CD_FLAG_NOCOPY flag in custom data layers where the mask is * zero for the layer type, so only layer types specified by the mask will be copied */ -void CustomData_set_only_copy(const struct CustomData *data, CustomDataMask mask); +void CustomData_set_only_copy(const struct CustomData *data, eCustomDataMask mask); /** * Copies data from one CustomData object to another @@ -309,7 +309,7 @@ void CustomData_bmesh_copy_data_exclude_by_type(const struct CustomData *source, struct CustomData *dest, void *src_block, void **dest_block, - CustomDataMask mask_exclude); + eCustomDataMask mask_exclude); /** * Copies data of a single layer of a given type. @@ -488,7 +488,7 @@ void CustomData_bmesh_free_block_data(struct CustomData *data, void *block); */ void CustomData_bmesh_free_block_data_exclude_by_type(struct CustomData *data, void *block, - CustomDataMask mask_exclude); + eCustomDataMask mask_exclude); /** * Copy custom data to/from layers as in mesh/derived-mesh, to edit-mesh @@ -593,14 +593,14 @@ void CustomData_external_remove(struct CustomData *data, struct ID *id, int type bool CustomData_external_test(struct CustomData *data, int type); void CustomData_external_write( - struct CustomData *data, struct ID *id, CustomDataMask mask, int totelem, int free); + struct CustomData *data, struct ID *id, eCustomDataMask mask, int totelem, int free); void CustomData_external_read(struct CustomData *data, struct ID *id, - CustomDataMask mask, + eCustomDataMask mask, int totelem); void CustomData_external_reload(struct CustomData *data, struct ID *id, - CustomDataMask mask, + eCustomDataMask mask, int totelem); /* Mesh-to-mesh transfer data. */ @@ -726,7 +726,7 @@ void CustomData_blend_write(BlendWriter *writer, CustomData *data, blender::Span<CustomDataLayer> layers_to_write, int count, - CustomDataMask cddata_mask, + eCustomDataMask cddata_mask, ID *id); #endif @@ -749,7 +749,7 @@ void CustomData_debug_info_from_layers(const struct CustomData *data, # include "BLI_cpp_type.hh" namespace blender::bke { -const CPPType *custom_data_type_to_cpp_type(const CustomDataType type); -CustomDataType cpp_type_to_custom_data_type(const CPPType &type); +const CPPType *custom_data_type_to_cpp_type(eCustomDataType type); +eCustomDataType cpp_type_to_custom_data_type(const CPPType &type); } // namespace blender::bke #endif diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 78d80ce200e..30c73e0fcc6 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -259,6 +259,18 @@ struct FCurve *BKE_fcurve_iter_step(struct FCurve *fcu_iter, const char rna_path /** * High level function to get an f-curve from C without having the RNA. + * + * If there is an action assigned to the `id`'s #AnimData, it will be searched for a matching + * F-curve first. Drivers are searched only if no valid action F-curve could be found. + * + * \note: Return pointer parameter (`r_driven`) is optional and may be NULL. + * + * \warning: In case no animation (from an Action) F-curve is found, returned value is always NULL. + * This means that this function will set `r_driven` to True in case a valid driver F-curve is + * found, but will not return said F-curve. In other words: + * - Animated with FCurve: returns the `FCurve*` and `*r_driven = false`. + * - Animated with driver: returns `NULL` and `*r_driven = true`. + * - Not animated: returns `NULL` and `*r_driven = false`. */ struct FCurve *id_data_find_fcurve( ID *id, void *data, struct StructRNA *type, const char *prop_name, int index, bool *r_driven); @@ -279,6 +291,25 @@ struct FCurve *id_data_find_fcurve( int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName); /** + * Find an F-Curve from its rna path and index. + * + * If there is an action assigned to the `animdata`, it will be searched for a matching F-curve + * first. Drivers are searched only if no valid action F-curve could be found. + * + * \note: Typically, indices in RNA arrays are stored separately in F-curves, so the rna_path + * should not include them (e.g. `rna_path='location[0]'` will not match any F-Curve on an Object, + * but `rna_path='location', rna_index=0` will if it exists). + * + * \note: Return pointer parameters (`r_action`, `r_driven` and `r_special`) are all optional and + * may be NULL. + */ +struct FCurve *BKE_animadata_fcurve_find_by_rna_path(struct AnimData *animdata, + const char *rna_path, + const int rna_index, + struct bAction **r_action, + bool *r_driven); + +/** * Find an f-curve based on an rna property. */ struct FCurve *BKE_fcurve_find_by_rna(struct PointerRNA *ptr, @@ -291,7 +322,9 @@ struct FCurve *BKE_fcurve_find_by_rna(struct PointerRNA *ptr, /** * Same as above, but takes a context data, * temp hack needed for complex paths like texture ones. - */ + * + * \param r_special Optional, ignored when NULL. Set to `true` if the given RNA `ptr` is a NLA + * strip, and the returned F-curve comes from this NLA strip. */ struct FCurve *BKE_fcurve_find_by_rna_context_ui(struct bContext *C, const struct PointerRNA *ptr, struct PropertyRNA *prop, diff --git a/source/blender/blenkernel/BKE_geometry_fields.hh b/source/blender/blenkernel/BKE_geometry_fields.hh index 9c86ab262ef..7c504826044 100644 --- a/source/blender/blenkernel/BKE_geometry_fields.hh +++ b/source/blender/blenkernel/BKE_geometry_fields.hh @@ -17,10 +17,10 @@ namespace blender::bke { class GeometryComponentFieldContext : public fn::FieldContext { private: const GeometryComponent &component_; - const AttributeDomain domain_; + const eAttrDomain domain_; public: - GeometryComponentFieldContext(const GeometryComponent &component, const AttributeDomain domain) + GeometryComponentFieldContext(const GeometryComponent &component, const eAttrDomain domain) : component_(component), domain_(domain) { } @@ -30,7 +30,7 @@ class GeometryComponentFieldContext : public fn::FieldContext { return component_; } - AttributeDomain domain() const + eAttrDomain domain() const { return domain_; } @@ -45,7 +45,7 @@ class GeometryFieldInput : public fn::FieldInput { ResourceScope &scope) const override; virtual GVArray get_varray_for_context(const GeometryComponent &component, - AttributeDomain domain, + eAttrDomain domain, IndexMask mask) const = 0; }; @@ -73,7 +73,7 @@ class AttributeFieldInput : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - AttributeDomain domain, + eAttrDomain domain, IndexMask mask) const override; std::string socket_inspection_name() const override; @@ -90,7 +90,7 @@ class IDAttributeFieldInput : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - AttributeDomain domain, + eAttrDomain domain, IndexMask mask) const override; std::string socket_inspection_name() const override; @@ -99,12 +99,12 @@ class IDAttributeFieldInput : public GeometryFieldInput { bool is_equal_to(const fn::FieldNode &other) const override; }; -VArray<float3> curve_normals_varray(const CurveComponent &component, const AttributeDomain domain); +VArray<float3> curve_normals_varray(const CurveComponent &component, const eAttrDomain domain); VArray<float3> mesh_normals_varray(const MeshComponent &mesh_component, const Mesh &mesh, const IndexMask mask, - const AttributeDomain domain); + eAttrDomain domain); class NormalFieldInput : public GeometryFieldInput { public: @@ -114,7 +114,7 @@ class NormalFieldInput : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask mask) const override; std::string socket_inspection_name() const override; @@ -153,7 +153,7 @@ class AnonymousAttributeFieldInput : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - AttributeDomain domain, + eAttrDomain domain, IndexMask mask) const override; std::string socket_inspection_name() const override; @@ -166,7 +166,7 @@ class CurveLengthFieldInput final : public GeometryFieldInput { public: CurveLengthFieldInput(); GVArray get_varray_for_context(const GeometryComponent &component, - AttributeDomain domain, + eAttrDomain domain, IndexMask mask) const final; uint64_t hash() const override; bool is_equal_to(const fn::FieldNode &other) const override; diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index c58420efceb..8d658c9be15 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -94,11 +94,11 @@ class GeometryComponent { * \note Conceptually this function is static, the result is always the same for different * instances of the same geometry component type. */ - bool attribute_domain_supported(AttributeDomain domain) const; + bool attribute_domain_supported(eAttrDomain domain) const; /** * Return the length of a specific domain, or 0 if the domain is not supported. */ - virtual int attribute_domain_num(AttributeDomain domain) const; + virtual int attribute_domain_num(eAttrDomain domain) const; /** * Return true if the attribute name corresponds to a built-in attribute with a hardcoded domain @@ -130,16 +130,16 @@ class GeometryComponent { * \return null if the interpolation is not implemented. */ blender::GVArray attribute_try_adapt_domain(const blender::GVArray &varray, - const AttributeDomain from_domain, - const AttributeDomain to_domain) const + const eAttrDomain from_domain, + const eAttrDomain to_domain) const { return this->attribute_try_adapt_domain_impl(varray, from_domain, to_domain); } /* Use instead of the method above when the type is known at compile time for type safety. */ template<typename T> blender::VArray<T> attribute_try_adapt_domain(const blender::VArray<T> &varray, - const AttributeDomain from_domain, - const AttributeDomain to_domain) const + const eAttrDomain from_domain, + const eAttrDomain to_domain) const { return this->attribute_try_adapt_domain_impl(varray, from_domain, to_domain) .template typed<T>(); @@ -156,8 +156,8 @@ class GeometryComponent { /** Returns true when the attribute has been created. */ bool attribute_try_create(const blender::bke::AttributeIDRef &attribute_id, - AttributeDomain domain, - const CustomDataType data_type, + eAttrDomain domain, + eCustomDataType data_type, const AttributeInit &initializer); /** @@ -182,8 +182,8 @@ class GeometryComponent { * interpolated or converted. */ blender::GVArray attribute_try_get_for_read(const blender::bke::AttributeIDRef &attribute_id, - AttributeDomain domain, - const CustomDataType data_type) const; + eAttrDomain domain, + eCustomDataType data_type) const; /** * Get a virtual array that refers to the data of an attribute, interpolated to the given domain. @@ -191,7 +191,7 @@ class GeometryComponent { * interpolated. */ blender::GVArray attribute_try_get_for_read(const blender::bke::AttributeIDRef &attribute_id, - AttributeDomain domain) const; + eAttrDomain domain) const; /** * Get a virtual array that refers to the data of an attribute converted to the given data type. @@ -199,7 +199,7 @@ class GeometryComponent { * cannot be converted. */ blender::bke::ReadAttributeLookup attribute_try_get_for_read( - const blender::bke::AttributeIDRef &attribute_id, const CustomDataType data_type) const; + const blender::bke::AttributeIDRef &attribute_id, eCustomDataType data_type) const; /** * Get a virtual array that refers to the data of an attribute, interpolated to the given domain @@ -207,17 +207,17 @@ class GeometryComponent { * contain a default value. This never returns null. */ blender::GVArray attribute_get_for_read(const blender::bke::AttributeIDRef &attribute_id, - AttributeDomain domain, - const CustomDataType data_type, + eAttrDomain domain, + eCustomDataType data_type, const void *default_value = nullptr) const; /* Use instead of the method above when the type is known at compile time for type safety. */ template<typename T> blender::VArray<T> attribute_get_for_read(const blender::bke::AttributeIDRef &attribute_id, - const AttributeDomain domain, + const eAttrDomain domain, const T &default_value) const { const blender::CPPType &cpp_type = blender::CPPType::get<T>(); - const CustomDataType type = blender::bke::cpp_type_to_custom_data_type(cpp_type); + const eCustomDataType type = blender::bke::cpp_type_to_custom_data_type(cpp_type); return this->attribute_get_for_read(attribute_id, domain, type, &default_value) .template typed<T>(); } @@ -234,18 +234,18 @@ class GeometryComponent { */ blender::bke::OutputAttribute attribute_try_get_for_output( const blender::bke::AttributeIDRef &attribute_id, - AttributeDomain domain, - const CustomDataType data_type, + eAttrDomain domain, + eCustomDataType data_type, const void *default_value = nullptr); /* Use instead of the method above when the type is known at compile time for type safety. */ template<typename T> blender::bke::OutputAttribute_Typed<T> attribute_try_get_for_output( const blender::bke::AttributeIDRef &attribute_id, - const AttributeDomain domain, + const eAttrDomain domain, const T default_value) { const blender::CPPType &cpp_type = blender::CPPType::get<T>(); - const CustomDataType data_type = blender::bke::cpp_type_to_custom_data_type(cpp_type); + const eCustomDataType data_type = blender::bke::cpp_type_to_custom_data_type(cpp_type); return this->attribute_try_get_for_output(attribute_id, domain, data_type, &default_value); } @@ -257,15 +257,15 @@ class GeometryComponent { */ blender::bke::OutputAttribute attribute_try_get_for_output_only( const blender::bke::AttributeIDRef &attribute_id, - AttributeDomain domain, - const CustomDataType data_type); + eAttrDomain domain, + eCustomDataType data_type); /* Use instead of the method above when the type is known at compile time for type safety. */ template<typename T> blender::bke::OutputAttribute_Typed<T> attribute_try_get_for_output_only( - const blender::bke::AttributeIDRef &attribute_id, const AttributeDomain domain) + const blender::bke::AttributeIDRef &attribute_id, const eAttrDomain domain) { const blender::CPPType &cpp_type = blender::CPPType::get<T>(); - const CustomDataType data_type = blender::bke::cpp_type_to_custom_data_type(cpp_type); + const eCustomDataType data_type = blender::bke::cpp_type_to_custom_data_type(cpp_type); return this->attribute_try_get_for_output_only(attribute_id, domain, data_type); } @@ -273,8 +273,8 @@ class GeometryComponent { virtual const blender::bke::ComponentAttributeProviders *get_attribute_providers() const; virtual blender::GVArray attribute_try_adapt_domain_impl(const blender::GVArray &varray, - AttributeDomain from_domain, - AttributeDomain to_domain) const; + eAttrDomain from_domain, + eAttrDomain to_domain) const; }; template<typename T> @@ -560,7 +560,7 @@ class MeshComponent : public GeometryComponent { */ Mesh *get_for_write(); - int attribute_domain_num(AttributeDomain domain) const final; + int attribute_domain_num(eAttrDomain domain) const final; bool is_empty() const final; @@ -573,8 +573,8 @@ class MeshComponent : public GeometryComponent { const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final; blender::GVArray attribute_try_adapt_domain_impl(const blender::GVArray &varray, - AttributeDomain from_domain, - AttributeDomain to_domain) const final; + eAttrDomain from_domain, + eAttrDomain to_domain) const final; }; /** @@ -623,7 +623,7 @@ class PointCloudComponent : public GeometryComponent { */ PointCloud *get_for_write(); - int attribute_domain_num(AttributeDomain domain) const final; + int attribute_domain_num(eAttrDomain domain) const final; bool is_empty() const final; @@ -664,7 +664,7 @@ class CurveComponentLegacy : public GeometryComponent { const CurveEval *get_for_read() const; CurveEval *get_for_write(); - int attribute_domain_num(AttributeDomain domain) const final; + int attribute_domain_num(eAttrDomain domain) const final; bool is_empty() const final; @@ -677,8 +677,8 @@ class CurveComponentLegacy : public GeometryComponent { const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final; blender::GVArray attribute_try_adapt_domain_impl(const blender::GVArray &varray, - AttributeDomain from_domain, - AttributeDomain to_domain) const final; + eAttrDomain from_domain, + eAttrDomain to_domain) const final; }; /** @@ -716,7 +716,7 @@ class CurveComponent : public GeometryComponent { const Curves *get_for_read() const; Curves *get_for_write(); - int attribute_domain_num(AttributeDomain domain) const final; + int attribute_domain_num(eAttrDomain domain) const final; bool is_empty() const final; @@ -735,8 +735,8 @@ class CurveComponent : public GeometryComponent { const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final; blender::GVArray attribute_try_adapt_domain_impl(const blender::GVArray &varray, - AttributeDomain from_domain, - AttributeDomain to_domain) const final; + eAttrDomain from_domain, + eAttrDomain to_domain) const final; }; /** @@ -964,7 +964,7 @@ class InstancesComponent : public GeometryComponent { blender::bke::CustomDataAttributes &attributes(); const blender::bke::CustomDataAttributes &attributes() const; - int attribute_domain_num(AttributeDomain domain) const final; + int attribute_domain_num(eAttrDomain domain) const final; void foreach_referenced_geometry( blender::FunctionRef<void(const GeometrySet &geometry_set)> callback) const; diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h index 60564d1282e..dc7a5ab003a 100644 --- a/source/blender/blenkernel/BKE_gpencil.h +++ b/source/blender/blenkernel/BKE_gpencil.h @@ -76,13 +76,13 @@ struct bGPdata; void BKE_gpencil_free_point_weights(struct MDeformVert *dvert); void BKE_gpencil_free_stroke_weights(struct bGPDstroke *gps); void BKE_gpencil_free_stroke_editcurve(struct bGPDstroke *gps); -/* free stroke, doesn't unlink from any listbase */ +/** Free stroke, doesn't unlink from any #ListBase. */ void BKE_gpencil_free_stroke(struct bGPDstroke *gps); -/* Free strokes belonging to a gp-frame */ +/** Free strokes belonging to a gp-frame. */ bool BKE_gpencil_free_strokes(struct bGPDframe *gpf); -/* Free all of a gp-layer's frames */ +/** Free all of a gp-layer's frames. */ void BKE_gpencil_free_frames(struct bGPDlayer *gpl); -/* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */ +/** Free all of the gp-layers for a viewport (list should be `&gpd->layers` or so). */ void BKE_gpencil_free_layers(struct ListBase *list); /** Free (or release) any data used by this grease pencil (does not free the gpencil itself). */ void BKE_gpencil_free_data(struct bGPdata *gpd, bool free_all); @@ -108,9 +108,9 @@ void BKE_gpencil_batch_cache_free(struct bGPdata *gpd); */ void BKE_gpencil_stroke_sync_selection(struct bGPdata *gpd, struct bGPDstroke *gps); void BKE_gpencil_curve_sync_selection(struct bGPdata *gpd, struct bGPDstroke *gps); -/* Assign unique stroke ID for selection. */ +/** Assign unique stroke ID for selection. */ void BKE_gpencil_stroke_select_index_set(struct bGPdata *gpd, struct bGPDstroke *gps); -/* Reset unique stroke ID for selection. */ +/** Reset unique stroke ID for selection. */ void BKE_gpencil_stroke_select_index_reset(struct bGPDstroke *gps); /** diff --git a/source/blender/blenkernel/BKE_lib_remap.h b/source/blender/blenkernel/BKE_lib_remap.h index f62225179bd..37b626fb4da 100644 --- a/source/blender/blenkernel/BKE_lib_remap.h +++ b/source/blender/blenkernel/BKE_lib_remap.h @@ -95,11 +95,11 @@ typedef enum eIDRemapType { */ void BKE_libblock_remap_multiple_locked(struct Main *bmain, struct IDRemapper *mappings, - const short remap_flags); + short remap_flags); void BKE_libblock_remap_multiple(struct Main *bmain, struct IDRemapper *mappings, - const short remap_flags); + short remap_flags); /** * Replace all references in given Main to \a old_id by \a new_id @@ -142,9 +142,9 @@ void BKE_libblock_relink_ex(struct Main *bmain, */ void BKE_libblock_relink_multiple(struct Main *bmain, struct LinkNode *ids, - const eIDRemapType remap_type, + eIDRemapType remap_type, struct IDRemapper *id_remapper, - const short remap_flags); + short remap_flags); /** * Remaps ID usages of given ID to their `id->newid` pointer if not None, and proceeds recursively diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h index 0e78f9d7e15..dfefe125a51 100644 --- a/source/blender/blenkernel/BKE_mesh_runtime.h +++ b/source/blender/blenkernel/BKE_mesh_runtime.h @@ -8,7 +8,7 @@ * This file contains access functions for the Mesh.runtime struct. */ -//#include "BKE_customdata.h" /* for CustomDataMask */ +//#include "BKE_customdata.h" /* for eCustomDataMask */ #ifdef __cplusplus extern "C" { diff --git a/source/blender/blenkernel/BKE_mesh_sample.hh b/source/blender/blenkernel/BKE_mesh_sample.hh index a942f3bb7ed..37c2ad7d3cb 100644 --- a/source/blender/blenkernel/BKE_mesh_sample.hh +++ b/source/blender/blenkernel/BKE_mesh_sample.hh @@ -69,7 +69,7 @@ class MeshAttributeInterpolator { const Span<int> looptri_indices); void sample_data(const GVArray &src, - AttributeDomain domain, + eAttrDomain domain, eAttributeMapMode mode, const GMutableSpan dst); diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 68fd4c46c40..f856008c555 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -501,8 +501,8 @@ typedef struct SculptSession { struct MPropCol *vcol; struct MLoopCol *mcol; - AttributeDomain vcol_domain; - CustomDataType vcol_type; + eAttrDomain vcol_domain; + eCustomDataType vcol_type; float *vmask; diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 5afc224b172..ca8b8f5cda6 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -552,7 +552,7 @@ PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node); void BKE_pbvh_node_color_buffer_free(PBVH *pbvh); bool BKE_pbvh_get_color_layer(const struct Mesh *me, CustomDataLayer **r_layer, - AttributeDomain *r_attr); + eAttrDomain *r_attr); /* Swaps colors at each element in indices (of domain pbvh->vcol_domain) * with values in colors. */ diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index edb301f06bf..9965b6f1351 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -136,7 +136,7 @@ void BKE_sound_remove_scene_sound(struct Scene *scene, void *handle); void BKE_sound_mute_scene_sound(void *handle, char mute); -void BKE_sound_move_scene_sound(struct Scene *scene, +void BKE_sound_move_scene_sound(const struct Scene *scene, void *handle, int startframe, int endframe, diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 371bd8ded6d..05b51e0c9fa 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -980,13 +980,10 @@ void BKE_pose_channels_remove(Object *ob, else { /* Maybe something the bone references is being removed instead? */ for (con = pchan->constraints.first; con; con = con->next) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); - + if (BKE_constraint_targets_get(con, &targets)) { for (ct = targets.first; ct; ct = ct->next) { if (ct->tar == ob) { if (ct->subtarget[0]) { @@ -998,9 +995,7 @@ void BKE_pose_channels_remove(Object *ob, } } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, 0); - } + BKE_constraint_targets_flush(con, &targets, 0); } } diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 94b85e42f96..eb4784bebff 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -4074,7 +4074,7 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float /* objects */ /* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets - * this tagged by Depsgraph on framechange. This optimization means that objects + * this tagged by Depsgraph on frame-change. This optimization means that objects * linked from other (not-visible) scenes will not need their data calculated. */ EVAL_ANIM_IDS(main->objects.first, 0); diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index cfddae7721b..fedcfc5c721 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -183,7 +183,7 @@ bool BKE_id_attribute_calc_unique_name(ID *id, const char *name, char *outname) } CustomDataLayer *BKE_id_attribute_new( - ID *id, const char *name, const int type, const AttributeDomain domain, ReportList *reports) + ID *id, const char *name, const int type, const eAttrDomain domain, ReportList *reports) { DomainInfo info[ATTR_DOMAIN_NUM]; get_domains(id, info); @@ -264,7 +264,7 @@ bool BKE_id_attribute_remove(ID *id, CustomDataLayer *layer, ReportList *reports CustomDataLayer *BKE_id_attribute_find(const ID *id, const char *name, const int type, - const AttributeDomain domain) + const eAttrDomain domain) { DomainInfo info[ATTR_DOMAIN_NUM]; get_domains(id, info); @@ -284,7 +284,37 @@ CustomDataLayer *BKE_id_attribute_find(const ID *id, return nullptr; } -int BKE_id_attributes_length(const ID *id, AttributeDomainMask domain_mask, CustomDataMask mask) +CustomDataLayer *BKE_id_attribute_search(const ID *id, + const char *name, + const eCustomDataMask type_mask, + const eAttrDomainMask domain_mask) +{ + DomainInfo info[ATTR_DOMAIN_NUM]; + get_domains(id, info); + + for (eAttrDomain domain = ATTR_DOMAIN_POINT; domain < ATTR_DOMAIN_NUM; + domain = static_cast<eAttrDomain>((static_cast<int>(domain)) + 1)) { + if (!(domain_mask & ATTR_DOMAIN_AS_MASK(domain))) { + continue; + } + + CustomData *customdata = info[domain].customdata; + if (customdata == NULL) { + return NULL; + } + + for (int i = 0; i < customdata->totlayer; i++) { + CustomDataLayer *layer = &customdata->layers[i]; + if ((CD_TYPE_AS_MASK(layer->type) & type_mask) && STREQ(layer->name, name)) { + return layer; + } + } + } + + return NULL; +} + +int BKE_id_attributes_length(const ID *id, eAttrDomainMask domain_mask, eCustomDataMask mask) { DomainInfo info[ATTR_DOMAIN_NUM]; get_domains(id, info); @@ -302,7 +332,7 @@ int BKE_id_attributes_length(const ID *id, AttributeDomainMask domain_mask, Cust return length; } -AttributeDomain BKE_id_attribute_domain(const ID *id, const CustomDataLayer *layer) +eAttrDomain BKE_id_attribute_domain(const ID *id, const CustomDataLayer *layer) { DomainInfo info[ATTR_DOMAIN_NUM]; get_domains(id, info); @@ -311,12 +341,12 @@ AttributeDomain BKE_id_attribute_domain(const ID *id, const CustomDataLayer *lay CustomData *customdata = info[domain].customdata; if (customdata && ARRAY_HAS_ITEM((CustomDataLayer *)layer, customdata->layers, customdata->totlayer)) { - return static_cast<AttributeDomain>(domain); + return static_cast<eAttrDomain>(domain); } } BLI_assert_msg(0, "Custom data layer not found in geometry"); - return static_cast<AttributeDomain>(ATTR_DOMAIN_POINT); + return static_cast<eAttrDomain>(ATTR_DOMAIN_POINT); } int BKE_id_attribute_data_length(ID *id, CustomDataLayer *layer) @@ -459,8 +489,8 @@ CustomData *BKE_id_attributes_iterator_next_domain(ID *id, CustomDataLayer *laye CustomDataLayer *BKE_id_attribute_from_index(ID *id, int lookup_index, - AttributeDomainMask domain_mask, - CustomDataMask layer_mask) + eAttrDomainMask domain_mask, + eCustomDataMask layer_mask) { DomainInfo info[ATTR_DOMAIN_NUM]; get_domains(id, info); @@ -493,27 +523,27 @@ CustomDataLayer *BKE_id_attribute_from_index(ID *id, /** Get list of domain types but with ATTR_DOMAIN_FACE and * ATTR_DOMAIN_CORNER swapped. */ -static void get_domains_types(AttributeDomain domains[ATTR_DOMAIN_NUM]) +static void get_domains_types(eAttrDomain domains[ATTR_DOMAIN_NUM]) { for (const int i : IndexRange(ATTR_DOMAIN_NUM)) { - domains[i] = static_cast<AttributeDomain>(i); + domains[i] = static_cast<eAttrDomain>(i); } /* Swap corner and face. */ - SWAP(AttributeDomain, domains[ATTR_DOMAIN_FACE], domains[ATTR_DOMAIN_CORNER]); + SWAP(eAttrDomain, domains[ATTR_DOMAIN_FACE], domains[ATTR_DOMAIN_CORNER]); } int BKE_id_attribute_to_index(const ID *id, const CustomDataLayer *layer, - AttributeDomainMask domain_mask, - CustomDataMask layer_mask) + eAttrDomainMask domain_mask, + eCustomDataMask layer_mask) { if (!layer) { return -1; } DomainInfo info[ATTR_DOMAIN_NUM]; - AttributeDomain domains[ATTR_DOMAIN_NUM]; + eAttrDomain domains[ATTR_DOMAIN_NUM]; get_domains_types(domains); get_domains(id, info); @@ -545,11 +575,11 @@ int BKE_id_attribute_to_index(const ID *id, CustomDataLayer *BKE_id_attribute_subset_active_get(const ID *id, int active_flag, - AttributeDomainMask domain_mask, - CustomDataMask mask) + eAttrDomainMask domain_mask, + eCustomDataMask mask) { DomainInfo info[ATTR_DOMAIN_NUM]; - AttributeDomain domains[ATTR_DOMAIN_NUM]; + eAttrDomain domains[ATTR_DOMAIN_NUM]; get_domains_types(domains); get_domains(id, info); @@ -583,17 +613,17 @@ CustomDataLayer *BKE_id_attribute_subset_active_get(const ID *id, void BKE_id_attribute_subset_active_set(ID *id, CustomDataLayer *layer, int active_flag, - AttributeDomainMask domain_mask, - CustomDataMask mask) + eAttrDomainMask domain_mask, + eCustomDataMask mask) { DomainInfo info[ATTR_DOMAIN_NUM]; - AttributeDomain domains[ATTR_DOMAIN_NUM]; + eAttrDomain domains[ATTR_DOMAIN_NUM]; get_domains_types(domains); get_domains(id, info); for (int i = 0; i < ATTR_DOMAIN_NUM; i++) { - AttributeDomainMask domain_mask2 = (AttributeDomainMask)(1 << domains[i]); + eAttrDomainMask domain_mask2 = (eAttrDomainMask)(1 << domains[i]); if (!(domain_mask2 & domain_mask) || !info[domains[i]].customdata) { continue; @@ -651,6 +681,7 @@ CustomDataLayer *BKE_id_attributes_color_find(const ID *id, const char *name) if (layer == nullptr) { layer = BKE_id_attribute_find(id, name, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_CORNER); } + return layer; } diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index e487bf4acf6..bc146d87e4c 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -63,7 +63,7 @@ bool allow_procedural_attribute_access(StringRef attribute_name) return !attribute_name.startswith(".selection"); } -static int attribute_data_type_complexity(const CustomDataType data_type) +static int attribute_data_type_complexity(const eCustomDataType data_type) { switch (data_type) { case CD_PROP_BOOL: @@ -93,12 +93,12 @@ static int attribute_data_type_complexity(const CustomDataType data_type) } } -CustomDataType attribute_data_type_highest_complexity(Span<CustomDataType> data_types) +eCustomDataType attribute_data_type_highest_complexity(Span<eCustomDataType> data_types) { int highest_complexity = INT_MIN; - CustomDataType most_complex_type = CD_PROP_COLOR; + eCustomDataType most_complex_type = CD_PROP_COLOR; - for (const CustomDataType data_type : data_types) { + for (const eCustomDataType data_type : data_types) { const int complexity = attribute_data_type_complexity(data_type); if (complexity > highest_complexity) { highest_complexity = complexity; @@ -113,7 +113,7 @@ CustomDataType attribute_data_type_highest_complexity(Span<CustomDataType> data_ * \note Generally the order should mirror the order of the domains * established in each component's ComponentAttributeProviders. */ -static int attribute_domain_priority(const AttributeDomain domain) +static int attribute_domain_priority(const eAttrDomain domain) { switch (domain) { case ATTR_DOMAIN_INSTANCE: @@ -135,12 +135,12 @@ static int attribute_domain_priority(const AttributeDomain domain) } } -AttributeDomain attribute_domain_highest_priority(Span<AttributeDomain> domains) +eAttrDomain attribute_domain_highest_priority(Span<eAttrDomain> domains) { int highest_priority = INT_MIN; - AttributeDomain highest_priority_domain = ATTR_DOMAIN_CORNER; + eAttrDomain highest_priority_domain = ATTR_DOMAIN_CORNER; - for (const AttributeDomain domain : domains) { + for (const eAttrDomain domain : domains) { const int priority = attribute_domain_priority(domain); if (priority > highest_priority) { highest_priority = priority; @@ -191,7 +191,7 @@ static AttributeIDRef attribute_id_from_custom_data_layer(const CustomDataLayer } static bool add_builtin_type_custom_data_layer_from_init(CustomData &custom_data, - const CustomDataType data_type, + const eCustomDataType data_type, const int domain_num, const AttributeInit &initializer) { @@ -226,7 +226,7 @@ static bool add_builtin_type_custom_data_layer_from_init(CustomData &custom_data } static void *add_generic_custom_data_layer(CustomData &custom_data, - const CustomDataType data_type, + const eCustomDataType data_type, const eCDAllocType alloctype, void *layer_data, const int domain_num, @@ -245,7 +245,7 @@ static void *add_generic_custom_data_layer(CustomData &custom_data, static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attribute_id, CustomData &custom_data, - const CustomDataType data_type, + const eCustomDataType data_type, const int domain_num, const AttributeInit &initializer) { @@ -459,7 +459,7 @@ ReadAttributeLookup CustomDataAttributeProvider::try_get_for_read( if (!custom_data_layer_matches_attribute_id(layer, attribute_id)) { continue; } - const CPPType *type = custom_data_type_to_cpp_type((CustomDataType)layer.type); + const CPPType *type = custom_data_type_to_cpp_type((eCustomDataType)layer.type); if (type == nullptr) { continue; } @@ -488,7 +488,7 @@ WriteAttributeLookup CustomDataAttributeProvider::try_get_for_write( CustomData_duplicate_referenced_layer_anonymous( custom_data, layer.type, &attribute_id.anonymous_id(), domain_num); } - const CPPType *type = custom_data_type_to_cpp_type((CustomDataType)layer.type); + const CPPType *type = custom_data_type_to_cpp_type((eCustomDataType)layer.type); if (type == nullptr) { continue; } @@ -508,7 +508,7 @@ bool CustomDataAttributeProvider::try_delete(GeometryComponent &component, const int domain_num = component.attribute_domain_num(domain_); for (const int i : IndexRange(custom_data->totlayer)) { const CustomDataLayer &layer = custom_data->layers[i]; - if (this->type_is_supported((CustomDataType)layer.type) && + if (this->type_is_supported((eCustomDataType)layer.type) && custom_data_layer_matches_attribute_id(layer, attribute_id)) { CustomData_free_layer(custom_data, layer.type, domain_num, i); return true; @@ -519,8 +519,8 @@ bool CustomDataAttributeProvider::try_delete(GeometryComponent &component, bool CustomDataAttributeProvider::try_create(GeometryComponent &component, const AttributeIDRef &attribute_id, - const AttributeDomain domain, - const CustomDataType data_type, + const eAttrDomain domain, + const eCustomDataType data_type, const AttributeInit &initializer) const { if (domain_ != domain) { @@ -552,7 +552,7 @@ bool CustomDataAttributeProvider::foreach_attribute(const GeometryComponent &com return true; } for (const CustomDataLayer &layer : Span(custom_data->layers, custom_data->totlayer)) { - const CustomDataType data_type = (CustomDataType)layer.type; + const eCustomDataType data_type = (eCustomDataType)layer.type; if (this->type_is_supported(data_type)) { AttributeMetaData meta_data{domain_, data_type}; const AttributeIDRef attribute_id = attribute_id_from_custom_data_layer(layer); @@ -650,7 +650,7 @@ bool NamedLegacyCustomDataProvider::foreach_attribute( } void NamedLegacyCustomDataProvider::foreach_domain( - const FunctionRef<void(AttributeDomain)> callback) const + const FunctionRef<void(eAttrDomain)> callback) const { callback(domain_); } @@ -693,7 +693,7 @@ std::optional<GSpan> CustomDataAttributes::get_for_read(const AttributeIDRef &at { for (const CustomDataLayer &layer : Span(data.layers, data.totlayer)) { if (custom_data_layer_matches_attribute_id(layer, attribute_id)) { - const CPPType *cpp_type = custom_data_type_to_cpp_type((CustomDataType)layer.type); + const CPPType *cpp_type = custom_data_type_to_cpp_type((eCustomDataType)layer.type); BLI_assert(cpp_type != nullptr); return GSpan(*cpp_type, layer.data, size_); } @@ -702,7 +702,7 @@ std::optional<GSpan> CustomDataAttributes::get_for_read(const AttributeIDRef &at } GVArray CustomDataAttributes::get_for_read(const AttributeIDRef &attribute_id, - const CustomDataType data_type, + const eCustomDataType data_type, const void *default_value) const { const CPPType *type = blender::bke::custom_data_type_to_cpp_type(data_type); @@ -726,7 +726,7 @@ std::optional<GMutableSpan> CustomDataAttributes::get_for_write(const AttributeI { for (CustomDataLayer &layer : MutableSpan(data.layers, data.totlayer)) { if (custom_data_layer_matches_attribute_id(layer, attribute_id)) { - const CPPType *cpp_type = custom_data_type_to_cpp_type((CustomDataType)layer.type); + const CPPType *cpp_type = custom_data_type_to_cpp_type((eCustomDataType)layer.type); BLI_assert(cpp_type != nullptr); return GMutableSpan(*cpp_type, layer.data, size_); } @@ -735,7 +735,7 @@ std::optional<GMutableSpan> CustomDataAttributes::get_for_write(const AttributeI } bool CustomDataAttributes::create(const AttributeIDRef &attribute_id, - const CustomDataType data_type) + const eCustomDataType data_type) { void *result = add_generic_custom_data_layer( data, data_type, CD_DEFAULT, nullptr, size_, attribute_id); @@ -743,7 +743,7 @@ bool CustomDataAttributes::create(const AttributeIDRef &attribute_id, } bool CustomDataAttributes::create_by_move(const AttributeIDRef &attribute_id, - const CustomDataType data_type, + const eCustomDataType data_type, void *buffer) { void *result = add_generic_custom_data_layer( @@ -776,10 +776,10 @@ void CustomDataAttributes::clear() } bool CustomDataAttributes::foreach_attribute(const AttributeForeachCallback callback, - const AttributeDomain domain) const + const eAttrDomain domain) const { for (const CustomDataLayer &layer : Span(data.layers, data.totlayer)) { - AttributeMetaData meta_data{domain, (CustomDataType)layer.type}; + AttributeMetaData meta_data{domain, (eCustomDataType)layer.type}; const AttributeIDRef attribute_id = attribute_id_from_custom_data_layer(layer); if (!callback(attribute_id, meta_data)) { return false; @@ -819,7 +819,7 @@ const blender::bke::ComponentAttributeProviders *GeometryComponent::get_attribut return nullptr; } -bool GeometryComponent::attribute_domain_supported(const AttributeDomain domain) const +bool GeometryComponent::attribute_domain_supported(const eAttrDomain domain) const { using namespace blender::bke; const ComponentAttributeProviders *providers = this->get_attribute_providers(); @@ -829,7 +829,7 @@ bool GeometryComponent::attribute_domain_supported(const AttributeDomain domain) return providers->supported_domains().contains(domain); } -int GeometryComponent::attribute_domain_num(const AttributeDomain UNUSED(domain)) const +int GeometryComponent::attribute_domain_num(const eAttrDomain UNUSED(domain)) const { return 0; } @@ -877,8 +877,8 @@ blender::bke::ReadAttributeLookup GeometryComponent::attribute_try_get_for_read( blender::GVArray GeometryComponent::attribute_try_adapt_domain_impl( const blender::GVArray &varray, - const AttributeDomain from_domain, - const AttributeDomain to_domain) const + const eAttrDomain from_domain, + const eAttrDomain to_domain) const { if (from_domain == to_domain) { return varray; @@ -949,8 +949,8 @@ void GeometryComponent::attributes_remove_anonymous() } bool GeometryComponent::attribute_try_create(const AttributeIDRef &attribute_id, - const AttributeDomain domain, - const CustomDataType data_type, + const eAttrDomain domain, + const eCustomDataType data_type, const AttributeInit &initializer) { using namespace blender::bke; @@ -1087,8 +1087,8 @@ static blender::GVArray try_adapt_data_type(blender::GVArray varray, blender::GVArray GeometryComponent::attribute_try_get_for_read( const AttributeIDRef &attribute_id, - const AttributeDomain domain, - const CustomDataType data_type) const + const eAttrDomain domain, + const eCustomDataType data_type) const { blender::bke::ReadAttributeLookup attribute = this->attribute_try_get_for_read(attribute_id); if (!attribute) { @@ -1116,7 +1116,7 @@ blender::GVArray GeometryComponent::attribute_try_get_for_read( } blender::GVArray GeometryComponent::attribute_try_get_for_read(const AttributeIDRef &attribute_id, - const AttributeDomain domain) const + const eAttrDomain domain) const { if (!this->attribute_domain_supported(domain)) { return {}; @@ -1135,7 +1135,7 @@ blender::GVArray GeometryComponent::attribute_try_get_for_read(const AttributeID } blender::bke::ReadAttributeLookup GeometryComponent::attribute_try_get_for_read( - const AttributeIDRef &attribute_id, const CustomDataType data_type) const + const AttributeIDRef &attribute_id, const eCustomDataType data_type) const { blender::bke::ReadAttributeLookup attribute = this->attribute_try_get_for_read(attribute_id); if (!attribute) { @@ -1152,8 +1152,8 @@ blender::bke::ReadAttributeLookup GeometryComponent::attribute_try_get_for_read( } blender::GVArray GeometryComponent::attribute_get_for_read(const AttributeIDRef &attribute_id, - const AttributeDomain domain, - const CustomDataType data_type, + const eAttrDomain domain, + const eCustomDataType data_type, const void *default_value) const { blender::GVArray varray = this->attribute_try_get_for_read(attribute_id, domain, data_type); @@ -1214,8 +1214,8 @@ static void save_output_attribute(OutputAttribute &output_attribute) else { attribute_id = varray.anonymous_attribute_id.extract(); } - const AttributeDomain domain = output_attribute.domain(); - const CustomDataType data_type = output_attribute.custom_data_type(); + const eAttrDomain domain = output_attribute.domain(); + const eCustomDataType data_type = output_attribute.custom_data_type(); const CPPType &cpp_type = output_attribute.cpp_type(); component.attribute_try_delete(attribute_id); @@ -1252,8 +1252,8 @@ static std::function<void(OutputAttribute &)> get_simple_output_attribute_save_m static OutputAttribute create_output_attribute(GeometryComponent &component, const AttributeIDRef &attribute_id, - const AttributeDomain domain, - const CustomDataType data_type, + const eAttrDomain domain, + const eCustomDataType data_type, const bool ignore_old_values, const void *default_value) { @@ -1358,17 +1358,15 @@ static OutputAttribute create_output_attribute(GeometryComponent &component, } OutputAttribute GeometryComponent::attribute_try_get_for_output(const AttributeIDRef &attribute_id, - const AttributeDomain domain, - const CustomDataType data_type, + const eAttrDomain domain, + const eCustomDataType data_type, const void *default_value) { return create_output_attribute(*this, attribute_id, domain, data_type, false, default_value); } OutputAttribute GeometryComponent::attribute_try_get_for_output_only( - const AttributeIDRef &attribute_id, - const AttributeDomain domain, - const CustomDataType data_type) + const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type) { return create_output_attribute(*this, attribute_id, domain, data_type, true, nullptr); } @@ -1382,17 +1380,17 @@ GVArray GeometryFieldInput::get_varray_for_context(const fn::FieldContext &conte if (const GeometryComponentFieldContext *geometry_context = dynamic_cast<const GeometryComponentFieldContext *>(&context)) { const GeometryComponent &component = geometry_context->geometry_component(); - const AttributeDomain domain = geometry_context->domain(); + const eAttrDomain domain = geometry_context->domain(); return this->get_varray_for_context(component, domain, mask); } return {}; } GVArray AttributeFieldInput::get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const { - const CustomDataType data_type = cpp_type_to_custom_data_type(*type_); + const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_); return component.attribute_try_get_for_read(name_, domain, data_type); } @@ -1416,7 +1414,7 @@ bool AttributeFieldInput::is_equal_to(const fn::FieldNode &other) const return false; } -static StringRef get_random_id_attribute_name(const AttributeDomain domain) +static StringRef get_random_id_attribute_name(const eAttrDomain domain) { switch (domain) { case ATTR_DOMAIN_POINT: @@ -1428,7 +1426,7 @@ static StringRef get_random_id_attribute_name(const AttributeDomain domain) } GVArray IDAttributeFieldInput::get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask mask) const { @@ -1461,10 +1459,10 @@ bool IDAttributeFieldInput::is_equal_to(const fn::FieldNode &other) const } GVArray AnonymousAttributeFieldInput::get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const { - const CustomDataType data_type = cpp_type_to_custom_data_type(*type_); + const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_); return component.attribute_try_get_for_read(anonymous_id_.get(), domain, data_type); } diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh index f0f47cb7a11..ac43754dd1a 100644 --- a/source/blender/blenkernel/intern/attribute_access_intern.hh +++ b/source/blender/blenkernel/intern/attribute_access_intern.hh @@ -47,16 +47,16 @@ class BuiltinAttributeProvider { protected: const std::string name_; - const AttributeDomain domain_; - const CustomDataType data_type_; + const eAttrDomain domain_; + const eCustomDataType data_type_; const CreatableEnum createable_; const WritableEnum writable_; const DeletableEnum deletable_; public: BuiltinAttributeProvider(std::string name, - const AttributeDomain domain, - const CustomDataType data_type, + const eAttrDomain domain, + const eCustomDataType data_type, const CreatableEnum createable, const WritableEnum writable, const DeletableEnum deletable) @@ -81,12 +81,12 @@ class BuiltinAttributeProvider { return name_; } - AttributeDomain domain() const + eAttrDomain domain() const { return domain_; } - CustomDataType data_type() const + eCustomDataType data_type() const { return data_type_; } @@ -106,8 +106,8 @@ class DynamicAttributesProvider { const AttributeIDRef &attribute_id) const = 0; virtual bool try_create(GeometryComponent &UNUSED(component), const AttributeIDRef &UNUSED(attribute_id), - const AttributeDomain UNUSED(domain), - const CustomDataType UNUSED(data_type), + const eAttrDomain UNUSED(domain), + const eCustomDataType UNUSED(data_type), const AttributeInit &UNUSED(initializer)) const { /* Some providers should not create new attributes. */ @@ -116,7 +116,7 @@ class DynamicAttributesProvider { virtual bool foreach_attribute(const GeometryComponent &component, const AttributeForeachCallback callback) const = 0; - virtual void foreach_domain(const FunctionRef<void(AttributeDomain)> callback) const = 0; + virtual void foreach_domain(const FunctionRef<void(eAttrDomain)> callback) const = 0; }; /** @@ -128,11 +128,11 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider { CD_MASK_PROP_FLOAT3 | CD_MASK_PROP_INT32 | CD_MASK_PROP_COLOR | CD_MASK_PROP_BOOL | CD_MASK_PROP_INT8 | CD_MASK_PROP_BYTE_COLOR; - const AttributeDomain domain_; + const eAttrDomain domain_; const CustomDataAccessInfo custom_data_access_; public: - CustomDataAttributeProvider(const AttributeDomain domain, + CustomDataAttributeProvider(const eAttrDomain domain, const CustomDataAccessInfo custom_data_access) : domain_(domain), custom_data_access_(custom_data_access) { @@ -148,20 +148,20 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider { bool try_create(GeometryComponent &component, const AttributeIDRef &attribute_id, - AttributeDomain domain, - const CustomDataType data_type, + eAttrDomain domain, + const eCustomDataType data_type, const AttributeInit &initializer) const final; bool foreach_attribute(const GeometryComponent &component, const AttributeForeachCallback callback) const final; - void foreach_domain(const FunctionRef<void(AttributeDomain)> callback) const final + void foreach_domain(const FunctionRef<void(eAttrDomain)> callback) const final { callback(domain_); } private: - bool type_is_supported(CustomDataType data_type) const + bool type_is_supported(eCustomDataType data_type) const { return ((1ULL << data_type) & supported_types_mask) != 0; } @@ -174,17 +174,17 @@ class NamedLegacyCustomDataProvider final : public DynamicAttributesProvider { private: using AsReadAttribute = GVArray (*)(const void *data, int domain_num); using AsWriteAttribute = GVMutableArray (*)(void *data, int domain_num); - const AttributeDomain domain_; - const CustomDataType attribute_type_; - const CustomDataType stored_type_; + const eAttrDomain domain_; + const eCustomDataType attribute_type_; + const eCustomDataType stored_type_; const CustomDataAccessInfo custom_data_access_; const AsReadAttribute as_read_attribute_; const AsWriteAttribute as_write_attribute_; public: - NamedLegacyCustomDataProvider(const AttributeDomain domain, - const CustomDataType attribute_type, - const CustomDataType stored_type, + NamedLegacyCustomDataProvider(const eAttrDomain domain, + const eCustomDataType attribute_type, + const eCustomDataType stored_type, const CustomDataAccessInfo custom_data_access, const AsReadAttribute as_read_attribute, const AsWriteAttribute as_write_attribute) @@ -204,7 +204,7 @@ class NamedLegacyCustomDataProvider final : public DynamicAttributesProvider { bool try_delete(GeometryComponent &component, const AttributeIDRef &attribute_id) const final; bool foreach_attribute(const GeometryComponent &component, const AttributeForeachCallback callback) const final; - void foreach_domain(const FunctionRef<void(AttributeDomain)> callback) const final; + void foreach_domain(const FunctionRef<void(eAttrDomain)> callback) const final; }; template<typename T> GVArray make_array_read_attribute(const void *data, const int domain_num) @@ -230,7 +230,7 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider { using AsWriteAttribute = GVMutableArray (*)(void *data, int domain_num); using UpdateOnRead = void (*)(const GeometryComponent &component); using UpdateOnWrite = void (*)(GeometryComponent &component); - const CustomDataType stored_type_; + const eCustomDataType stored_type_; const CustomDataAccessInfo custom_data_access_; const AsReadAttribute as_read_attribute_; const AsWriteAttribute as_write_attribute_; @@ -239,9 +239,9 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider { public: BuiltinCustomDataLayerProvider(std::string attribute_name, - const AttributeDomain domain, - const CustomDataType attribute_type, - const CustomDataType stored_type, + const eAttrDomain domain, + const eCustomDataType attribute_type, + const eCustomDataType stored_type, const CreatableEnum creatable, const WritableEnum writable, const DeletableEnum deletable, @@ -288,7 +288,7 @@ class ComponentAttributeProviders { /** * All the domains that are supported by at least one of the providers above. */ - VectorSet<AttributeDomain> supported_domains_; + VectorSet<eAttrDomain> supported_domains_; public: ComponentAttributeProviders(Span<const BuiltinAttributeProvider *> builtin_attribute_providers, @@ -301,7 +301,7 @@ class ComponentAttributeProviders { supported_domains_.add(provider->domain()); } for (const DynamicAttributesProvider *provider : dynamic_attribute_providers) { - provider->foreach_domain([&](AttributeDomain domain) { supported_domains_.add(domain); }); + provider->foreach_domain([&](eAttrDomain domain) { supported_domains_.add(domain); }); } } @@ -315,7 +315,7 @@ class ComponentAttributeProviders { return dynamic_attribute_providers_; } - Span<AttributeDomain> supported_domains() const + Span<eAttrDomain> supported_domains() const { return supported_domains_; } diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 76c6dc1d5e7..b71bcef229a 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -996,9 +996,11 @@ static void collection_tag_update_parent_recursive(Main *bmain, } } -static Collection *collection_parent_editable_find_recursive(Collection *collection) +static Collection *collection_parent_editable_find_recursive(const ViewLayer *view_layer, + Collection *collection) { - if (!ID_IS_LINKED(collection) && !ID_IS_OVERRIDE_LIBRARY(collection)) { + if (!ID_IS_LINKED(collection) && !ID_IS_OVERRIDE_LIBRARY(collection) && + (view_layer == NULL || BKE_view_layer_has_collection(view_layer, collection))) { return collection; } @@ -1009,10 +1011,16 @@ static Collection *collection_parent_editable_find_recursive(Collection *collect LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->parents) { if (!ID_IS_LINKED(collection_parent->collection) && !ID_IS_OVERRIDE_LIBRARY(collection_parent->collection)) { + if (view_layer != NULL && + !BKE_view_layer_has_collection(view_layer, collection_parent->collection)) { + /* In case this parent collection is not in given view_layer, there is no point in + * searching in its ancestors either, we can skip that whole parenting branch. */ + continue; + } return collection_parent->collection; } Collection *editable_collection = collection_parent_editable_find_recursive( - collection_parent->collection); + view_layer, collection_parent->collection); if (editable_collection != NULL) { return editable_collection; } @@ -1110,11 +1118,23 @@ bool BKE_collection_object_add_notest(Main *bmain, Collection *collection, Objec bool BKE_collection_object_add(Main *bmain, Collection *collection, Object *ob) { + return BKE_collection_viewlayer_object_add(bmain, NULL, collection, ob); +} + +bool BKE_collection_viewlayer_object_add(Main *bmain, + const ViewLayer *view_layer, + Collection *collection, + Object *ob) +{ if (collection == NULL) { return false; } - collection = collection_parent_editable_find_recursive(collection); + collection = collection_parent_editable_find_recursive(view_layer, collection); + + if (collection == NULL) { + return false; + } return BKE_collection_object_add_notest(bmain, collection, ob); } diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 35f2f94bc91..6ffb3299869 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -6191,6 +6191,40 @@ bool BKE_constraint_is_nonlocal_in_liboverride(const Object *ob, const bConstrai /* -------- Target-Matrix Stuff ------- */ +int BKE_constraint_targets_get(struct bConstraint *con, struct ListBase *r_targets) +{ + BLI_listbase_clear(r_targets); + + const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); + + if (!cti) { + return 0; + } + + int count = 0; + + /* Constraint-specific targets. */ + if (cti->get_constraint_targets) { + count = cti->get_constraint_targets(con, r_targets); + } + + return count; +} + +void BKE_constraint_targets_flush(struct bConstraint *con, struct ListBase *targets, bool no_copy) +{ + const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); + + if (!cti) { + return; + } + + /* Release the constraint-specific targets. */ + if (cti->flush_constraint_targets) { + cti->flush_constraint_targets(con, targets, no_copy); + } +} + void BKE_constraint_target_matrix_get(struct Depsgraph *depsgraph, Scene *scene, bConstraint *con, diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index 0cd324cfe2c..58380a1a35f 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -315,8 +315,8 @@ static ResultOffsets calculate_result_offsets(const CurvesInfo &info, const bool return result; } -static AttributeDomain get_attribute_domain_for_mesh(const MeshComponent &mesh, - const AttributeIDRef &attribute_id) +static eAttrDomain get_attribute_domain_for_mesh(const MeshComponent &mesh, + const AttributeIDRef &attribute_id) { /* Only use a different domain if it is builtin and must only exist on one domain. */ if (!mesh.attribute_is_builtin(attribute_id)) { @@ -456,7 +456,7 @@ static void copy_main_point_data_to_mesh_faces(const Span<T> src, static void copy_main_point_domain_attribute_to_mesh(const CurvesInfo &curves_info, const ResultOffsets &offsets, - const AttributeDomain dst_domain, + const eAttrDomain dst_domain, const GSpan src_all, GMutableSpan dst_all) { @@ -538,7 +538,7 @@ static void copy_profile_point_data_to_mesh_faces(const Span<T> src, static void copy_profile_point_domain_attribute_to_mesh(const CurvesInfo &curves_info, const ResultOffsets &offsets, - const AttributeDomain dst_domain, + const eAttrDomain dst_domain, const GSpan src_all, GMutableSpan dst_all) { @@ -597,7 +597,7 @@ static void copy_indices_to_offset_ranges(const VArray<T> &src, static void copy_curve_domain_attribute_to_mesh(const ResultOffsets &mesh_offsets, const Span<int> curve_indices, - const AttributeDomain dst_domain, + const eAttrDomain dst_domain, const GVArray &src, GMutableSpan dst) { @@ -728,11 +728,11 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, } main_attributes.add_new(id); - const AttributeDomain src_domain = meta_data.domain; - const CustomDataType type = meta_data.data_type; + const eAttrDomain src_domain = meta_data.domain; + const eCustomDataType type = meta_data.data_type; GVArray src = main_component.attribute_try_get_for_read(id, src_domain, type); - const AttributeDomain dst_domain = get_attribute_domain_for_mesh(mesh_component, id); + const eAttrDomain dst_domain = get_attribute_domain_for_mesh(mesh_component, id); OutputAttribute dst = mesh_component.attribute_try_get_for_output_only(id, dst_domain, type); if (!dst) { return true; @@ -763,11 +763,11 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, if (!should_add_attribute_to_mesh(profile_component, mesh_component, id)) { return true; } - const AttributeDomain src_domain = meta_data.domain; - const CustomDataType type = meta_data.data_type; + const eAttrDomain src_domain = meta_data.domain; + const eCustomDataType type = meta_data.data_type; GVArray src = profile_component.attribute_try_get_for_read(id, src_domain, type); - const AttributeDomain dst_domain = get_attribute_domain_for_mesh(mesh_component, id); + const eAttrDomain dst_domain = get_attribute_domain_for_mesh(mesh_component, id); OutputAttribute dst = mesh_component.attribute_try_get_for_output_only(id, dst_domain, type); if (!dst) { return true; diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc index ab9dd702630..9abd5a7fdf0 100644 --- a/source/blender/blenkernel/intern/curves.cc +++ b/source/blender/blenkernel/intern/curves.cc @@ -89,6 +89,10 @@ static void curves_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, dst.curve_offsets = static_cast<int *>(MEM_dupallocN(src.curve_offsets)); + if (curves_src->surface_uv_map != nullptr) { + curves_dst->surface_uv_map = BLI_strdup(curves_src->surface_uv_map); + } + dst.runtime = MEM_new<bke::CurvesGeometryRuntime>(__func__); dst.runtime->type_counts = src.runtime->type_counts; @@ -108,6 +112,7 @@ static void curves_free_data(ID *id) BKE_curves_batch_cache_free(curves); MEM_SAFE_FREE(curves->mat); + MEM_SAFE_FREE(curves->surface_uv_map); } static void curves_foreach_id(ID *id, LibraryForeachIDData *data) @@ -148,6 +153,8 @@ static void curves_blend_write(BlendWriter *writer, ID *id, const void *id_addre BLO_write_int32_array(writer, curves->geometry.curve_num + 1, curves->geometry.curve_offsets); + BLO_write_string(writer, curves->surface_uv_map); + BLO_write_pointer_array(writer, curves->totcol, curves->mat); if (curves->adt) { BKE_animdata_blend_write(writer, curves->adt); @@ -167,6 +174,8 @@ static void curves_blend_read_data(BlendDataReader *reader, ID *id) BLO_read_int32_array(reader, curves->geometry.curve_num + 1, &curves->geometry.curve_offsets); + BLO_read_data_address(reader, &curves->surface_uv_map); + curves->geometry.runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__); /* Recalculate curve type count cache that isn't saved in files. */ @@ -199,8 +208,8 @@ IDTypeInfo IDType_ID_CV = { /*id_filter */ FILTER_ID_CV, /*main_listbase_index */ INDEX_ID_CV, /*struct_size */ sizeof(Curves), - /*name */ "Hair Curves", - /*name_plural */ "Hair Curves", + /*name */ "Curves", + /*name_plural */ "curves", /*translation_context */ BLT_I18NCONTEXT_ID_CURVES, /*flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, /*asset_type_info */ nullptr, diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 0fd58a52f81..c2e67d853c9 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -37,6 +37,8 @@ static const std::string ATTR_NURBS_WEIGHT = "nurbs_weight"; static const std::string ATTR_NURBS_KNOTS_MODE = "knots_mode"; static const std::string ATTR_SURFACE_TRIANGLE_INDEX = "surface_triangle_index"; static const std::string ATTR_SURFACE_TRIANGLE_COORDINATE = "surface_triangle_coordinate"; +static const std::string ATTR_SELECTION_POINT_FLOAT = ".selection_point_float"; +static const std::string ATTR_SELECTION_CURVE_FLOAT = ".selection_curve_float"; /* -------------------------------------------------------------------- */ /** \name Constructors/Destructor @@ -158,30 +160,29 @@ CurvesGeometry::~CurvesGeometry() /** \name Accessors * \{ */ -static int domain_num(const CurvesGeometry &curves, const AttributeDomain domain) +static int domain_num(const CurvesGeometry &curves, const eAttrDomain domain) { return domain == ATTR_DOMAIN_POINT ? curves.points_num() : curves.curves_num(); } -static CustomData &domain_custom_data(CurvesGeometry &curves, const AttributeDomain domain) +static CustomData &domain_custom_data(CurvesGeometry &curves, const eAttrDomain domain) { return domain == ATTR_DOMAIN_POINT ? curves.point_data : curves.curve_data; } -static const CustomData &domain_custom_data(const CurvesGeometry &curves, - const AttributeDomain domain) +static const CustomData &domain_custom_data(const CurvesGeometry &curves, const eAttrDomain domain) { return domain == ATTR_DOMAIN_POINT ? curves.point_data : curves.curve_data; } template<typename T> static VArray<T> get_varray_attribute(const CurvesGeometry &curves, - const AttributeDomain domain, + const eAttrDomain domain, const StringRefNull name, const T default_value) { const int num = domain_num(curves, domain); - const CustomDataType type = cpp_type_to_custom_data_type(CPPType::get<T>()); + const eCustomDataType type = cpp_type_to_custom_data_type(CPPType::get<T>()); const CustomData &custom_data = domain_custom_data(curves, domain); const T *data = (const T *)CustomData_get_layer_named(&custom_data, type, name.c_str()); @@ -193,12 +194,12 @@ static VArray<T> get_varray_attribute(const CurvesGeometry &curves, template<typename T> static Span<T> get_span_attribute(const CurvesGeometry &curves, - const AttributeDomain domain, + const eAttrDomain domain, const StringRefNull name) { const int num = domain_num(curves, domain); const CustomData &custom_data = domain_custom_data(curves, domain); - const CustomDataType type = cpp_type_to_custom_data_type(CPPType::get<T>()); + const eCustomDataType type = cpp_type_to_custom_data_type(CPPType::get<T>()); T *data = (T *)CustomData_get_layer_named(&custom_data, type, name.c_str()); if (data == nullptr) { @@ -209,12 +210,12 @@ static Span<T> get_span_attribute(const CurvesGeometry &curves, template<typename T> static MutableSpan<T> get_mutable_attribute(CurvesGeometry &curves, - const AttributeDomain domain, + const eAttrDomain domain, const StringRefNull name, const T default_value = T()) { const int num = domain_num(curves, domain); - const CustomDataType type = cpp_type_to_custom_data_type(CPPType::get<T>()); + const eCustomDataType type = cpp_type_to_custom_data_type(CPPType::get<T>()); CustomData &custom_data = domain_custom_data(curves, domain); T *data = (T *)CustomData_duplicate_referenced_layer_named( @@ -438,6 +439,26 @@ MutableSpan<float2> CurvesGeometry::surface_triangle_coords_for_write() return get_mutable_attribute<float2>(*this, ATTR_DOMAIN_CURVE, ATTR_SURFACE_TRIANGLE_COORDINATE); } +VArray<float> CurvesGeometry::selection_point_float() const +{ + return get_varray_attribute<float>(*this, ATTR_DOMAIN_POINT, ATTR_SELECTION_POINT_FLOAT, 1.0f); +} + +MutableSpan<float> CurvesGeometry::selection_point_float_for_write() +{ + return get_mutable_attribute<float>(*this, ATTR_DOMAIN_POINT, ATTR_SELECTION_POINT_FLOAT, 1.0f); +} + +VArray<float> CurvesGeometry::selection_curve_float() const +{ + return get_varray_attribute<float>(*this, ATTR_DOMAIN_CURVE, ATTR_SELECTION_CURVE_FLOAT, 1.0f); +} + +MutableSpan<float> CurvesGeometry::selection_curve_float_for_write() +{ + return get_mutable_attribute<float>(*this, ATTR_DOMAIN_CURVE, ATTR_SELECTION_CURVE_FLOAT, 1.0f); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -1084,7 +1105,7 @@ void CurvesGeometry::update_customdata_pointers() static void *ensure_customdata_layer(CustomData &custom_data, const StringRefNull name, - const CustomDataType data_type, + const eCustomDataType data_type, const int tot_elements) { for (const int other_layer_i : IndexRange(custom_data.totlayer)) { @@ -1153,7 +1174,7 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves, CustomData &new_point_data = new_curves.point_data; for (const int layer_i : IndexRange(old_point_data.totlayer)) { const CustomDataLayer &old_layer = old_point_data.layers[layer_i]; - const CustomDataType data_type = static_cast<CustomDataType>(old_layer.type); + const eCustomDataType data_type = static_cast<eCustomDataType>(old_layer.type); const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type); const void *src_buffer = old_layer.data; @@ -1180,7 +1201,7 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves, CustomData &new_curve_data = new_curves.curve_data; for (const int layer_i : IndexRange(old_curve_data.totlayer)) { const CustomDataLayer &old_layer = old_curve_data.layers[layer_i]; - const CustomDataType data_type = static_cast<CustomDataType>(old_layer.type); + const eCustomDataType data_type = static_cast<eCustomDataType>(old_layer.type); const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type); const void *src_buffer = old_layer.data; @@ -1246,7 +1267,7 @@ static void reverse_swap_curve_point_data(const CurvesGeometry &curves, static bool layer_matches_name_and_type(const CustomDataLayer &layer, const StringRef name, - const CustomDataType type) + const eCustomDataType type) { if (layer.type != type) { return false; @@ -1289,7 +1310,7 @@ void CurvesGeometry::reverse_curves(const IndexMask curves_to_reverse) continue; } - const CustomDataType data_type = static_cast<CustomDataType>(layer.type); + const eCustomDataType data_type = static_cast<eCustomDataType>(layer.type); attribute_math::convert_to_static_type(data_type, [&](auto dummy) { using T = decltype(dummy); reverse_curve_point_data<T>( @@ -1408,8 +1429,8 @@ static GVArray adapt_curve_domain_curve_to_point(const CurvesGeometry &curves, } GVArray CurvesGeometry::adapt_domain(const GVArray &varray, - const AttributeDomain from, - const AttributeDomain to) const + const eAttrDomain from, + const eAttrDomain to) const { if (!varray) { return {}; diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index da5c8389be2..a63528835ee 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -55,6 +55,7 @@ /* only for customdata_data_transfer_interp_normal_normals */ #include "data_transfer_intern.h" +using blender::IndexRange; using blender::Span; using blender::Vector; @@ -521,6 +522,22 @@ static void layerCopy_propInt(const void *source, void *dest, int count) memcpy(dest, source, sizeof(MIntProperty) * count); } +static void layerInterp_propInt(const void **sources, + const float *weights, + const float *UNUSED(sub_weights), + int count, + void *dest) +{ + float result = 0.0f; + for (const int i : IndexRange(count)) { + const float weight = weights[i]; + const float src = *static_cast<const int *>(sources[i]); + result += src * weight; + } + const int rounded_result = static_cast<int>(round(result)); + *static_cast<int *>(dest) = rounded_result; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -1683,7 +1700,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { N_("Int"), layerCopy_propInt, nullptr, - nullptr, + layerInterp_propInt, nullptr}, /* 12: CD_PROP_STRING */ {sizeof(MStringProperty), @@ -2222,7 +2239,7 @@ static bool customdata_typemap_is_valid(const CustomData *data) bool CustomData_merge(const struct CustomData *source, struct CustomData *dest, - CustomDataMask mask, + eCustomDataMask mask, eCDAllocType alloctype, int totelem) { @@ -2324,7 +2341,7 @@ void CustomData_realloc(CustomData *data, int totelem) void CustomData_copy(const struct CustomData *source, struct CustomData *dest, - CustomDataMask mask, + eCustomDataMask mask, eCDAllocType alloctype, int totelem) { @@ -2386,7 +2403,7 @@ void CustomData_free(CustomData *data, int totelem) CustomData_reset(data); } -void CustomData_free_typemask(struct CustomData *data, int totelem, CustomDataMask mask) +void CustomData_free_typemask(struct CustomData *data, int totelem, eCustomDataMask mask) { for (int i = 0; i < data->totlayer; i++) { CustomDataLayer *layer = &data->layers[i]; @@ -2917,7 +2934,7 @@ int CustomData_number_of_layers(const CustomData *data, int type) return number; } -int CustomData_number_of_layers_typemask(const CustomData *data, CustomDataMask mask) +int CustomData_number_of_layers_typemask(const CustomData *data, eCustomDataMask mask) { int number = 0; @@ -3060,7 +3077,7 @@ void CustomData_free_temporary(CustomData *data, int totelem) } } -void CustomData_set_only_copy(const struct CustomData *data, CustomDataMask mask) +void CustomData_set_only_copy(const struct CustomData *data, eCustomDataMask mask) { for (int i = 0; i < data->totlayer; i++) { if (!(mask & CD_TYPE_AS_MASK(data->layers[i].type))) { @@ -3675,7 +3692,7 @@ void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype) bool CustomData_bmesh_merge(const CustomData *source, CustomData *dest, - CustomDataMask mask, + eCustomDataMask mask, eCDAllocType alloctype, BMesh *bm, const char htype) @@ -3824,7 +3841,7 @@ static void CustomData_bmesh_alloc_block(CustomData *data, void **block) void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data, void *block, - const CustomDataMask mask_exclude) + const eCustomDataMask mask_exclude) { if (block == nullptr) { return; @@ -3871,7 +3888,7 @@ void CustomData_bmesh_copy_data_exclude_by_type(const CustomData *source, CustomData *dest, void *src_block, void **dest_block, - const CustomDataMask mask_exclude) + const eCustomDataMask mask_exclude) { /* Note that having a version of this function without a 'mask_exclude' * would cause too much duplicate code, so add a check instead. */ @@ -4583,7 +4600,10 @@ static void customdata_external_filename(char filepath[FILE_MAX], BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(id)); } -void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask mask, int totelem) +void CustomData_external_reload(CustomData *data, + ID *UNUSED(id), + eCustomDataMask mask, + int totelem) { for (int i = 0; i < data->totlayer; i++) { CustomDataLayer *layer = &data->layers[i]; @@ -4601,7 +4621,7 @@ void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask } } -void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem) +void CustomData_external_read(CustomData *data, ID *id, eCustomDataMask mask, int totelem) { CustomDataExternal *external = data->external; CustomDataLayer *layer; @@ -4675,7 +4695,7 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int } void CustomData_external_write( - CustomData *data, ID *id, CustomDataMask mask, int totelem, int free) + CustomData *data, ID *id, eCustomDataMask mask, int totelem, int free) { CustomDataExternal *external = data->external; int update = 0; @@ -5166,7 +5186,7 @@ void CustomData_blend_write(BlendWriter *writer, CustomData *data, Span<CustomDataLayer> layers_to_write, int count, - CustomDataMask cddata_mask, + eCustomDataMask cddata_mask, ID *id) { /* write external customdata (not for undo) */ @@ -5367,7 +5387,7 @@ namespace blender::bke { /** \name Custom Data C++ API * \{ */ -const blender::CPPType *custom_data_type_to_cpp_type(const CustomDataType type) +const blender::CPPType *custom_data_type_to_cpp_type(const eCustomDataType type) { switch (type) { case CD_PROP_FLOAT: @@ -5392,7 +5412,7 @@ const blender::CPPType *custom_data_type_to_cpp_type(const CustomDataType type) return nullptr; } -CustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type) +eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type) { if (type.is<float>()) { return CD_PROP_FLOAT; @@ -5418,7 +5438,7 @@ CustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type) if (type.is<ColorGeometry4b>()) { return CD_PROP_BYTE_COLOR; } - return static_cast<CustomDataType>(-1); + return static_cast<eCustomDataType>(-1); } /** \} */ diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 952d5df299c..48ba6a851d2 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -229,16 +229,13 @@ FCurve *id_data_find_fcurve( return NULL; } - /* Animation takes priority over drivers. */ - if (adt->action && adt->action->curves.first) { - fcu = BKE_fcurve_find(&adt->action->curves, path, index); - } - - /* If not animated, check if driven. */ - if (fcu == NULL && adt->drivers.first) { - fcu = BKE_fcurve_find(&adt->drivers, path, index); - if (fcu && r_driven) { - *r_driven = true; + /* FIXME: The way drivers are handled here (always NULL-ifying `fcu`) is very weird, this needs + * to be re-checked I think?. */ + bool is_driven = false; + fcu = BKE_animadata_fcurve_find_by_rna_path(adt, path, index, NULL, &is_driven); + if (is_driven) { + if (r_driven != NULL) { + *r_driven = is_driven; } fcu = NULL; } @@ -339,6 +336,47 @@ int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, con return matches; } +FCurve *BKE_animadata_fcurve_find_by_rna_path( + AnimData *animdata, const char *rna_path, int rna_index, bAction **r_action, bool *r_driven) +{ + if (r_driven != NULL) { + *r_driven = false; + } + if (r_action != NULL) { + *r_action = NULL; + } + + const bool has_action_fcurves = animdata->action != NULL && + !BLI_listbase_is_empty(&animdata->action->curves); + const bool has_drivers = !BLI_listbase_is_empty(&animdata->drivers); + + /* Animation takes priority over drivers. */ + if (has_action_fcurves) { + FCurve *fcu = BKE_fcurve_find(&animdata->action->curves, rna_path, rna_index); + + if (fcu != NULL) { + if (r_action != NULL) { + *r_action = animdata->action; + } + return fcu; + } + } + + /* If not animated, check if driven. */ + if (has_drivers) { + FCurve *fcu = BKE_fcurve_find(&animdata->drivers, rna_path, rna_index); + + if (fcu != NULL) { + if (r_driven != NULL) { + *r_driven = true; + } + return fcu; + } + } + + return NULL; +} + FCurve *BKE_fcurve_find_by_rna(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, @@ -360,17 +398,18 @@ FCurve *BKE_fcurve_find_by_rna_context_ui(bContext *UNUSED(C), bool *r_driven, bool *r_special) { - FCurve *fcu = NULL; - - *r_driven = false; - *r_special = false; - - if (r_animdata) { + if (r_animdata != NULL) { *r_animdata = NULL; } - if (r_action) { + if (r_action != NULL) { *r_action = NULL; } + if (r_driven != NULL) { + *r_driven = false; + } + if (r_special) { + *r_special = false; + } /* Special case for NLA Control Curves... */ if (BKE_nlastrip_has_curves_for_property(ptr, prop)) { @@ -379,59 +418,46 @@ FCurve *BKE_fcurve_find_by_rna_context_ui(bContext *UNUSED(C), /* Set the special flag, since it cannot be a normal action/driver * if we've been told to start looking here... */ - *r_special = true; + if (r_special) { + *r_special = true; + } + + *r_driven = false; + if (r_animdata) { + *r_animdata = NULL; + } + if (r_action) { + *r_action = NULL; + } /* The F-Curve either exists or it doesn't here... */ - fcu = BKE_fcurve_find(&strip->fcurves, RNA_property_identifier(prop), rnaindex); - return fcu; + return BKE_fcurve_find(&strip->fcurves, RNA_property_identifier(prop), rnaindex); } /* There must be some RNA-pointer + property combo. */ if (!prop || !ptr->owner_id || !RNA_property_animateable(ptr, prop)) { - return fcu; + return NULL; } AnimData *adt = BKE_animdata_from_id(ptr->owner_id); if (adt == NULL) { - return fcu; + return NULL; } - const bool has_action_fcurves = adt->action != NULL && - !BLI_listbase_is_empty(&adt->action->curves); - const bool has_drivers = !BLI_listbase_is_empty(&adt->drivers); - /* XXX This function call can become a performance bottleneck. */ - char *path = RNA_path_from_ID_to_property(ptr, prop); - - /* Standard F-Curve - Animation (Action) or Drivers. */ - /* Animation takes priority over drivers. */ - /* XXX: The logic here is duplicated with a function up above. */ - if (has_action_fcurves) { - fcu = BKE_fcurve_find(&adt->action->curves, path, rnaindex); - - if (fcu) { - if (r_action) { - *r_action = adt->action; - } - if (r_animdata) { - *r_animdata = adt; - } - } + char *rna_path = RNA_path_from_ID_to_property(ptr, prop); + if (rna_path == NULL) { + return NULL; } - /* If not animated, check if driven. */ - if (fcu == NULL && has_drivers) { - fcu = BKE_fcurve_find(&adt->drivers, path, rnaindex); + /* Standard F-Curve from animdata - Animation (Action) or Drivers. */ + FCurve *fcu = BKE_animadata_fcurve_find_by_rna_path(adt, rna_path, rnaindex, r_action, r_driven); - if (fcu) { - if (r_animdata) { - *r_animdata = adt; - } - *r_driven = true; - } + if (fcu != NULL && r_animdata != NULL) { + *r_animdata = adt; } - MEM_SAFE_FREE(path); + MEM_freeN(rna_path); return fcu; } @@ -999,9 +1025,8 @@ static void UNUSED_FUNCTION(bezt_add_to_cfra_elem)(ListBase *lb, BezTriple *bezt * \{ */ /* Some utilities for working with FPoints (i.e. 'sampled' animation curve data, such as - * data imported from BVH/Mocap files), which are specialized for use with high density datasets, - * which BezTriples/Keyframe data are ill equipped to do. - */ + * data imported from BVH/motion-capture files), which are specialized for use with high density + * datasets, which BezTriples/Keyframe data are ill equipped to do. */ float fcurve_samplingcb_evalcurve(FCurve *fcu, void *UNUSED(data), float evaltime) { diff --git a/source/blender/blenkernel/intern/geometry_component_curve.cc b/source/blender/blenkernel/intern/geometry_component_curve.cc index a28afc8ddca..898869c3c44 100644 --- a/source/blender/blenkernel/intern/geometry_component_curve.cc +++ b/source/blender/blenkernel/intern/geometry_component_curve.cc @@ -114,7 +114,7 @@ void CurveComponentLegacy::ensure_owns_direct_data() /** \name Attribute Access Helper Functions * \{ */ -int CurveComponentLegacy::attribute_domain_num(const AttributeDomain domain) const +int CurveComponentLegacy::attribute_domain_num(const eAttrDomain domain) const { if (curve_ == nullptr) { return 0; @@ -308,10 +308,9 @@ static GVArray adapt_curve_domain_spline_to_point(const CurveEval &curve, GVArra } // namespace blender::bke -GVArray CurveComponentLegacy::attribute_try_adapt_domain_impl( - const GVArray &varray, - const AttributeDomain from_domain, - const AttributeDomain to_domain) const +GVArray CurveComponentLegacy::attribute_try_adapt_domain_impl(const GVArray &varray, + const eAttrDomain from_domain, + const eAttrDomain to_domain) const { if (!varray) { return {}; @@ -366,7 +365,7 @@ class BuiltinSplineAttributeProvider final : public BuiltinAttributeProvider { public: BuiltinSplineAttributeProvider(std::string attribute_name, - const CustomDataType attribute_type, + const eCustomDataType attribute_type, const WritableEnum writable, const AsReadAttribute as_read_attribute, const AsWriteAttribute as_write_attribute) @@ -577,7 +576,7 @@ static void point_attribute_materialize_to_uninitialized(Span<Span<T>> data, } static GVArray varray_from_initializer(const AttributeInit &initializer, - const CustomDataType data_type, + const eCustomDataType data_type, const Span<SplinePtr> splines) { switch (initializer.type) { @@ -604,7 +603,7 @@ static GVArray varray_from_initializer(const AttributeInit &initializer, static bool create_point_attribute(GeometryComponent &component, const AttributeIDRef &attribute_id, const AttributeInit &initializer, - const CustomDataType data_type) + const eCustomDataType data_type) { CurveEval *curve = get_curve_from_component_for_write(component); if (curve == nullptr || curve->splines().size() == 0) { @@ -1306,8 +1305,8 @@ class DynamicPointAttributeProvider final : public DynamicAttributesProvider { bool try_create(GeometryComponent &component, const AttributeIDRef &attribute_id, - const AttributeDomain domain, - const CustomDataType data_type, + const eAttrDomain domain, + const eCustomDataType data_type, const AttributeInit &initializer) const final { BLI_assert(this->type_is_supported(data_type)); @@ -1336,12 +1335,12 @@ class DynamicPointAttributeProvider final : public DynamicAttributesProvider { return true; } - void foreach_domain(const FunctionRef<void(AttributeDomain)> callback) const final + void foreach_domain(const FunctionRef<void(eAttrDomain)> callback) const final { callback(ATTR_DOMAIN_POINT); } - bool type_is_supported(CustomDataType data_type) const + bool type_is_supported(eCustomDataType data_type) const { return ((1ULL << data_type) & supported_types_mask) != 0; } diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index 9b023d12a7d..0003961c033 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -208,7 +208,7 @@ static Array<float3> curve_normal_point_domain(const bke::CurvesGeometry &curves return results; } -VArray<float3> curve_normals_varray(const CurveComponent &component, const AttributeDomain domain) +VArray<float3> curve_normals_varray(const CurveComponent &component, const eAttrDomain domain) { if (!component.has_curves()) { return {}; @@ -244,7 +244,7 @@ VArray<float3> curve_normals_varray(const CurveComponent &component, const Attri * \{ */ static VArray<float> construct_curve_length_gvarray(const CurveComponent &component, - const AttributeDomain domain) + const eAttrDomain domain) { if (!component.has_curves()) { return {}; @@ -279,7 +279,7 @@ CurveLengthFieldInput::CurveLengthFieldInput() } GVArray CurveLengthFieldInput::get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const { if (component.type() == GEO_COMPONENT_TYPE_CURVE) { @@ -308,7 +308,7 @@ bool CurveLengthFieldInput::is_equal_to(const fn::FieldNode &other) const /** \name Attribute Access Helper Functions * \{ */ -int CurveComponent::attribute_domain_num(const AttributeDomain domain) const +int CurveComponent::attribute_domain_num(const eAttrDomain domain) const { if (curves_ == nullptr) { return 0; @@ -325,8 +325,8 @@ int CurveComponent::attribute_domain_num(const AttributeDomain domain) const } GVArray CurveComponent::attribute_try_adapt_domain_impl(const GVArray &varray, - const AttributeDomain from_domain, - const AttributeDomain to_domain) const + const eAttrDomain from_domain, + const eAttrDomain to_domain) const { return blender::bke::CurvesGeometry::wrap(curves_->geometry) .adapt_domain(varray, from_domain, to_domain); diff --git a/source/blender/blenkernel/intern/geometry_component_instances.cc b/source/blender/blenkernel/intern/geometry_component_instances.cc index e56a7ca4dd8..653be03b991 100644 --- a/source/blender/blenkernel/intern/geometry_component_instances.cc +++ b/source/blender/blenkernel/intern/geometry_component_instances.cc @@ -366,7 +366,7 @@ blender::Span<int> InstancesComponent::almost_unique_ids() const return almost_unique_ids_; } -int InstancesComponent::attribute_domain_num(const AttributeDomain domain) const +int InstancesComponent::attribute_domain_num(const eAttrDomain domain) const { if (domain != ATTR_DOMAIN_INSTANCE) { return 0; diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 5ac9a03f43c..8a021e596bd 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -119,7 +119,7 @@ namespace blender::bke { VArray<float3> mesh_normals_varray(const MeshComponent &mesh_component, const Mesh &mesh, const IndexMask mask, - const AttributeDomain domain) + const eAttrDomain domain) { switch (domain) { case ATTR_DOMAIN_FACE: { @@ -169,7 +169,7 @@ VArray<float3> mesh_normals_varray(const MeshComponent &mesh_component, /** \name Attribute Access * \{ */ -int MeshComponent::attribute_domain_num(const AttributeDomain domain) const +int MeshComponent::attribute_domain_num(const eAttrDomain domain) const { if (mesh_ == nullptr) { return 0; @@ -747,10 +747,9 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v } // namespace blender::bke -blender::GVArray MeshComponent::attribute_try_adapt_domain_impl( - const blender::GVArray &varray, - const AttributeDomain from_domain, - const AttributeDomain to_domain) const +blender::GVArray MeshComponent::attribute_try_adapt_domain_impl(const blender::GVArray &varray, + const eAttrDomain from_domain, + const eAttrDomain to_domain) const { if (!varray) { return {}; @@ -1115,7 +1114,7 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider { return true; } - void foreach_domain(const FunctionRef<void(AttributeDomain)> callback) const final + void foreach_domain(const FunctionRef<void(eAttrDomain)> callback) const final { callback(ATTR_DOMAIN_POINT); } diff --git a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc index 6de123c7cb9..facdbed265d 100644 --- a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc +++ b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc @@ -104,7 +104,7 @@ void PointCloudComponent::ensure_owns_direct_data() /** \name Attribute Access * \{ */ -int PointCloudComponent::attribute_domain_num(const AttributeDomain domain) const +int PointCloudComponent::attribute_domain_num(const eAttrDomain domain) const { if (pointcloud_ == nullptr) { return 0; diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc index 40e36ced199..10226bc6990 100644 --- a/source/blender/blenkernel/intern/geometry_set.cc +++ b/source/blender/blenkernel/intern/geometry_set.cc @@ -470,7 +470,7 @@ void GeometrySet::gather_attributes_for_propagation( return; } - AttributeDomain domain = meta_data.domain; + eAttrDomain domain = meta_data.domain; if (dst_component_type != GEO_COMPONENT_TYPE_INSTANCES && domain == ATTR_DOMAIN_INSTANCE) { domain = ATTR_DOMAIN_POINT; } @@ -567,7 +567,7 @@ void GeometrySet::modify_geometry_sets(ForeachSubGeometryCallback callback) namespace blender::bke { GVArray NormalFieldInput::get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask mask) const { if (component.type() == GEO_COMPONENT_TYPE_MESH) { diff --git a/source/blender/blenkernel/intern/image_gpu.cc b/source/blender/blenkernel/intern/image_gpu.cc index bed79a318e8..6edb9e1b24c 100644 --- a/source/blender/blenkernel/intern/image_gpu.cc +++ b/source/blender/blenkernel/intern/image_gpu.cc @@ -718,12 +718,31 @@ static void gpu_texture_update_from_ibuf( int tex_offset = ibuf->channels * (y * ibuf->x + x); const bool store_premultiplied = BKE_image_has_gpu_texture_premultiplied_alpha(ima, ibuf); - if (rect_float == nullptr) { - /* Byte pixels. */ - if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { - const bool compress_as_srgb = !IMB_colormanagement_space_is_scene_linear( - ibuf->rect_colorspace); + if (rect_float) { + /* Float image is already in scene linear colorspace or non-color data by + * convention, no colorspace conversion needed. But we do require 4 channels + * currently. */ + if (ibuf->channels != 4 || scaled || !store_premultiplied) { + rect_float = (float *)MEM_mallocN(sizeof(float[4]) * w * h, __func__); + if (rect_float == nullptr) { + return; + } + tex_stride = w; + tex_offset = 0; + + IMB_colormanagement_imbuf_to_float_texture( + rect_float, x, y, w, h, ibuf, store_premultiplied); + } + } + else { + /* Byte image is in original colorspace from the file, and may need conversion. */ + if (IMB_colormanagement_space_is_data(ibuf->rect_colorspace) || + IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace)) { + /* Non-color data, just store buffer as is. */ + } + else if (IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace)) { + /* sRGB or scene linear, store as byte texture that the GPU can decode directly. */ rect = (uchar *)MEM_mallocN(sizeof(uchar[4]) * w * h, __func__); if (rect == nullptr) { return; @@ -734,13 +753,10 @@ static void gpu_texture_update_from_ibuf( /* Convert to scene linear with sRGB compression, and premultiplied for * correct texture interpolation. */ - IMB_colormanagement_imbuf_to_byte_texture( - rect, x, y, w, h, ibuf, compress_as_srgb, store_premultiplied); + IMB_colormanagement_imbuf_to_byte_texture(rect, x, y, w, h, ibuf, store_premultiplied); } - } - else { - /* Float pixels. */ - if (ibuf->channels != 4 || scaled || !store_premultiplied) { + else { + /* Other colorspace, store as float texture to avoid precision loss. */ rect_float = (float *)MEM_mallocN(sizeof(float[4]) * w * h, __func__); if (rect_float == nullptr) { return; diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc index 6bfdaf9b522..9dda3762553 100644 --- a/source/blender/blenkernel/intern/image_save.cc +++ b/source/blender/blenkernel/intern/image_save.cc @@ -274,6 +274,12 @@ static void image_save_post(ReportList *reports, if (opts->do_newpath) { BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name)); BLI_strncpy(ima->filepath, filepath, sizeof(ima->filepath)); + + /* only image path, never ibuf */ + if (opts->relative) { + const char *relbase = ID_BLEND_PATH(opts->bmain, &ima->id); + BLI_path_rel(ima->filepath, relbase); /* only after saving */ + } } ibuf->userflags &= ~IB_BITMAPDIRTY; @@ -303,12 +309,6 @@ static void image_save_post(ReportList *reports, ima->type = IMA_TYPE_IMAGE; } - /* only image path, never ibuf */ - if (opts->relative) { - const char *relbase = ID_BLEND_PATH(opts->bmain, &ima->id); - BLI_path_rel(ima->filepath, relbase); /* only after saving */ - } - /* Update image file color space when saving to another color space. */ const bool linear_float_output = BKE_imtype_requires_linear_float(opts->im_format.imtype); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 399c30dfb63..7a18b0043c0 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -120,7 +120,7 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int CustomData_MeshMasks mask = CD_MASK_MESH; if (mesh_src->id.tag & LIB_TAG_NO_MAIN) { - /* For copies in depsgraph, keep data like origindex and orco. */ + /* For copies in depsgraph, keep data like #CD_ORIGINDEX and #CD_ORCO. */ CustomData_MeshMasks_update(&mask, &CD_MASK_DERIVEDMESH); } diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index c960a7f35f1..85aed01ce52 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -375,7 +375,7 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source) while ((layer = BKE_id_attribute_from_index( const_cast<ID *>(&source->id), i++, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL))) { - AttributeDomain domain = BKE_id_attribute_domain(&source->id, layer); + eAttrDomain domain = BKE_id_attribute_domain(&source->id, layer); CustomData *target_cdata = domain == ATTR_DOMAIN_POINT ? &target->vdata : &target->ldata; const CustomData *source_cdata = domain == ATTR_DOMAIN_POINT ? &source->vdata : &source->ldata; diff --git a/source/blender/blenkernel/intern/mesh_sample.cc b/source/blender/blenkernel/intern/mesh_sample.cc index 33b051c792c..7595c08a208 100644 --- a/source/blender/blenkernel/intern/mesh_sample.cc +++ b/source/blender/blenkernel/intern/mesh_sample.cc @@ -204,7 +204,7 @@ Span<float3> MeshAttributeInterpolator::ensure_nearest_weights() } void MeshAttributeInterpolator::sample_data(const GVArray &src, - const AttributeDomain domain, + const eAttrDomain domain, const eAttributeMapMode mode, const GMutableSpan dst) { diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc index d16f7eaf588..9b2697ecc84 100644 --- a/source/blender/blenkernel/intern/mesh_validate.cc +++ b/source/blender/blenkernel/intern/mesh_validate.cc @@ -926,7 +926,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, } static bool mesh_validate_customdata(CustomData *data, - CustomDataMask mask, + eCustomDataMask mask, const uint totitems, const bool do_verbose, const bool do_fixes, @@ -953,7 +953,7 @@ static bool mesh_validate_customdata(CustomData *data, } if (mask != 0) { - CustomDataMask layer_typemask = CD_TYPE_AS_MASK(layer->type); + eCustomDataMask layer_typemask = CD_TYPE_AS_MASK(layer->type); if ((layer_typemask & mask) == 0) { PRINT_ERR("\tCustomDataLayer type %d which isn't in the mask\n", layer->type); ok = false; diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 55b9951c52d..c8b87c27697 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -2271,10 +2271,14 @@ Object *BKE_object_add(Main *bmain, ViewLayer *view_layer, int type, const char Object *ob = object_add_common(bmain, view_layer, type, name); LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer); - BKE_collection_object_add(bmain, layer_collection->collection, ob); + BKE_collection_viewlayer_object_add(bmain, view_layer, layer_collection->collection, ob); + /* Note: There is no way to be sure that #BKE_collection_viewlayer_object_add will actually + * manage to find a valid collection in given `view_layer` to add the new object to. */ Base *base = BKE_view_layer_base_find(view_layer, ob); - BKE_view_layer_base_select_and_set_active(view_layer, base); + if (base != nullptr) { + BKE_view_layer_base_select_and_set_active(view_layer, base); + } return ob; } @@ -2479,21 +2483,16 @@ static void copy_object_pose(Object *obn, const Object *ob, const int flag) * BKE_library_remap stuff, but... * the flush_constraint_targets callback am not sure about, so will delay that for now. */ LISTBASE_FOREACH (bConstraint *, con, &chan->constraints) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {nullptr, nullptr}; - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); - + if (BKE_constraint_targets_get(con, &targets)) { LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) { if (ct->tar == ob) { ct->tar = obn; } } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, false); - } + BKE_constraint_targets_flush(con, &targets, false); } } } @@ -5484,11 +5483,9 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph, /* also update constraint targets */ LISTBASE_FOREACH (bConstraint *, con, &ob->constraints) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {nullptr, nullptr}; - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); + if (BKE_constraint_targets_get(con, &targets)) { LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) { if (ct->tar) { BKE_object_modifier_update_subframe( @@ -5496,9 +5493,7 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph, } } /* free temp targets */ - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, false); - } + BKE_constraint_targets_flush(con, &targets, false); } } } diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 9d75ff9d24c..819fd85d5f5 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -1676,7 +1676,7 @@ static void sculpt_update_object(Depsgraph *depsgraph, ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK); CustomDataLayer *layer; - AttributeDomain domain; + eAttrDomain domain; if (BKE_pbvh_get_color_layer(me, &layer, &domain)) { if (layer->type == CD_PROP_COLOR) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index a5f7f73af70..b44b70bcd55 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -2276,7 +2276,7 @@ void psys_emitter_customdata_mask(ParticleSystem *psys, CustomData_MeshMasks *r_ r_cddata_masks->fmask |= CD_MASK_MTFACE; } - /* ask for vertexgroups if we need them */ + /* Ask for vertex-groups if we need them. */ for (i = 0; i < PSYS_TOT_VG; i++) { if (psys->vgroup[i]) { r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 4be48efb2b5..c461b7f108d 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -1216,8 +1216,8 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, MEM_freeN(element_sum); MEM_freeN(element_map); - /* For hair, sort by origindex (allows optimization's in rendering), */ - /* however with virtual parents the children need to be in random order. */ + /* For hair, sort by #CD_ORIGINDEX (allows optimization's in rendering), + * however with virtual parents the children need to be in random order. */ if (part->type == PART_HAIR && !(part->childtype == PART_CHILD_FACES && part->parents != 0.0f)) { const int *orig_index = NULL; diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 8345f493f46..28d635bdc65 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1265,7 +1265,7 @@ static int pbvh_get_buffers_update_flags(PBVH *UNUSED(pbvh)) return update_flags; } -bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, AttributeDomain *r_attr) +bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, eAttrDomain *r_attr) { CustomDataLayer *layer = BKE_id_attributes_active_color_get((ID *)me); @@ -1275,7 +1275,7 @@ bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, Attribu return false; } - AttributeDomain domain = BKE_id_attribute_domain((ID *)me, layer); + eAttrDomain domain = BKE_id_attribute_domain((ID *)me, layer); if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) { *r_layer = NULL; @@ -1341,7 +1341,7 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata, break; case PBVH_FACES: { CustomDataLayer *layer = NULL; - AttributeDomain domain; + eAttrDomain domain; BKE_pbvh_get_color_layer(pbvh->mesh, &layer, &domain); @@ -2545,7 +2545,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh, } if (origco) { - /* intersect with backuped original coordinates */ + /* Intersect with backed-up original coordinates. */ hit |= ray_face_nearest_tri(ray_start, ray_normal, origco[face_verts[0]], diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index be6e95426c2..dec93826b9b 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -44,7 +44,7 @@ using blender::IndexRange; namespace blender::bke { template<typename Func> -inline void to_static_color_type(const CustomDataType type, const Func &func) +inline void to_static_color_type(const eCustomDataType type, const Func &func) { switch (type) { case CD_PROP_COLOR: @@ -146,7 +146,7 @@ static void pbvh_vertex_color_set(PBVH &pbvh, int vertex, const float color[4]) extern "C" { void BKE_pbvh_vertex_color_get(const PBVH *pbvh, int vertex, float r_color[4]) { - blender::bke::to_static_color_type(CustomDataType(pbvh->color_layer->type), [&](auto dummy) { + blender::bke::to_static_color_type(eCustomDataType(pbvh->color_layer->type), [&](auto dummy) { using T = decltype(dummy); blender::bke::pbvh_vertex_color_get<T>(*pbvh, vertex, r_color); }); @@ -154,7 +154,7 @@ void BKE_pbvh_vertex_color_get(const PBVH *pbvh, int vertex, float r_color[4]) void BKE_pbvh_vertex_color_set(PBVH *pbvh, int vertex, const float color[4]) { - blender::bke::to_static_color_type(CustomDataType(pbvh->color_layer->type), [&](auto dummy) { + blender::bke::to_static_color_type(eCustomDataType(pbvh->color_layer->type), [&](auto dummy) { using T = decltype(dummy); blender::bke::pbvh_vertex_color_set<T>(*pbvh, vertex, color); }); @@ -165,7 +165,7 @@ void BKE_pbvh_swap_colors(PBVH *pbvh, const int indices_num, float (*r_colors)[4]) { - blender::bke::to_static_color_type(CustomDataType(pbvh->color_layer->type), [&](auto dummy) { + blender::bke::to_static_color_type(eCustomDataType(pbvh->color_layer->type), [&](auto dummy) { using T = decltype(dummy); T *pbvh_colors = static_cast<T *>(pbvh->color_layer->data); for (const int i : IndexRange(indices_num)) { @@ -181,7 +181,7 @@ void BKE_pbvh_store_colors(PBVH *pbvh, const int indices_num, float (*r_colors)[4]) { - blender::bke::to_static_color_type(CustomDataType(pbvh->color_layer->type), [&](auto dummy) { + blender::bke::to_static_color_type(eCustomDataType(pbvh->color_layer->type), [&](auto dummy) { using T = decltype(dummy); T *pbvh_colors = static_cast<T *>(pbvh->color_layer->data); for (const int i : IndexRange(indices_num)) { @@ -199,7 +199,7 @@ void BKE_pbvh_store_colors_vertex(PBVH *pbvh, BKE_pbvh_store_colors(pbvh, indices, indices_num, r_colors); } else { - blender::bke::to_static_color_type(CustomDataType(pbvh->color_layer->type), [&](auto dummy) { + blender::bke::to_static_color_type(eCustomDataType(pbvh->color_layer->type), [&](auto dummy) { using T = decltype(dummy); for (const int i : IndexRange(indices_num)) { blender::bke::pbvh_vertex_color_get<T>(*pbvh, indices[i], r_colors[i]); diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index 5527b6b3e3a..4bfdf025e93 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -199,7 +199,7 @@ struct PBVH { const struct MeshElemMap *pmap; CustomDataLayer *color_layer; - AttributeDomain color_domain; + eAttrDomain color_domain; bool is_drawing; diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index de5589cf5dc..5bafce15b34 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -54,6 +54,7 @@ #include "SEQ_sequencer.h" #include "SEQ_sound.h" +#include "SEQ_time.h" static void sound_free_audio(bSound *sound); @@ -719,8 +720,8 @@ void *BKE_sound_scene_add_scene_sound_defaults(Scene *scene, Sequence *sequence) { return BKE_sound_scene_add_scene_sound(scene, sequence, - sequence->startdisp, - sequence->enddisp, + SEQ_time_left_handle_frame_get(sequence), + SEQ_time_right_handle_frame_get(sequence), sequence->startofs + sequence->anim_startofs); } @@ -745,8 +746,8 @@ void *BKE_sound_add_scene_sound_defaults(Scene *scene, Sequence *sequence) { return BKE_sound_add_scene_sound(scene, sequence, - sequence->startdisp, - sequence->enddisp, + SEQ_time_left_handle_frame_get(sequence), + SEQ_time_right_handle_frame_get(sequence), sequence->startofs + sequence->anim_startofs); } @@ -760,8 +761,12 @@ void BKE_sound_mute_scene_sound(void *handle, char mute) AUD_SequenceEntry_setMuted(handle, mute); } -void BKE_sound_move_scene_sound( - Scene *scene, void *handle, int startframe, int endframe, int frameskip, double audio_offset) +void BKE_sound_move_scene_sound(const Scene *scene, + void *handle, + int startframe, + int endframe, + int frameskip, + double audio_offset) { sound_verify_evaluated_id(&scene->id); const double fps = FPS; @@ -774,8 +779,8 @@ void BKE_sound_move_scene_sound_defaults(Scene *scene, Sequence *sequence) if (sequence->scene_sound) { BKE_sound_move_scene_sound(scene, sequence->scene_sound, - sequence->startdisp, - sequence->enddisp, + SEQ_time_left_handle_frame_get(sequence), + SEQ_time_right_handle_frame_get(sequence), sequence->startofs + sequence->anim_startofs, 0.0); } @@ -1344,7 +1349,7 @@ void BKE_sound_remove_scene_sound(Scene *UNUSED(scene), void *UNUSED(handle)) void BKE_sound_mute_scene_sound(void *UNUSED(handle), char UNUSED(mute)) { } -void BKE_sound_move_scene_sound(Scene *UNUSED(scene), +void BKE_sound_move_scene_sound(const Scene *UNUSED(scene), void *UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), diff --git a/source/blender/blenkernel/intern/subdiv_ccg_mask.c b/source/blender/blenkernel/intern/subdiv_ccg_mask.c index 04a274d0215..1290f1e0834 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg_mask.c +++ b/source/blender/blenkernel/intern/subdiv_ccg_mask.c @@ -155,7 +155,7 @@ static void mask_init_functions(SubdivCCGMaskEvaluator *mask_evaluator) bool BKE_subdiv_ccg_mask_init_from_paint(SubdivCCGMaskEvaluator *mask_evaluator, const struct Mesh *mesh) { - if (CustomData_get_layer(&mesh->ldata, CD_GRID_PAINT_MASK)) { + if (!CustomData_get_layer(&mesh->ldata, CD_GRID_PAINT_MASK)) { return false; } /* Allocate all required memory. */ diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index e846dc2d807..ca4130d6bc4 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -44,7 +44,7 @@ typedef struct SubdivMeshContext { /* UV layers interpolation. */ int num_uv_layers; MLoopUV *uv_layers[MAX_MTFACE]; - /* Orco interpolation. */ + /* Original coordinates (ORCO) interpolation. */ float (*orco)[3]; float (*cloth_orco)[3]; /* Per-subdivided vertex counter of averaged values. */ diff --git a/source/blender/blenlib/BLI_assert.h b/source/blender/blenlib/BLI_assert.h index 9bb7f3bfa8b..4a7fae6e98c 100644 --- a/source/blender/blenlib/BLI_assert.h +++ b/source/blender/blenlib/BLI_assert.h @@ -73,7 +73,7 @@ void _BLI_assert_unreachable_print(const char *file, int line, const char *funct # define BLI_STATIC_ASSERT(a, msg) _STATIC_ASSERT(a); # endif #elif defined(__COVERITY__) -/* Workaround error with coverity */ +/* Workaround error with COVERITY. */ # define BLI_STATIC_ASSERT(a, msg) #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */ diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh index d02760d9178..3fce2947d0d 100644 --- a/source/blender/blenlib/BLI_generic_virtual_array.hh +++ b/source/blender/blenlib/BLI_generic_virtual_array.hh @@ -61,7 +61,9 @@ class GVArrayImpl { /* A generic version of #VMutableArrayImpl. */ class GVMutableArrayImpl : public GVArrayImpl { public: - GVMutableArrayImpl(const CPPType &type, int64_t size); + GVMutableArrayImpl(const CPPType &type, int64_t size) : GVArrayImpl(type, size) + { + } virtual void set_by_copy(int64_t index, const void *value); virtual void set_by_relocate(int64_t index, void *value); @@ -105,7 +107,7 @@ class GVArrayCommon { Storage storage_; protected: - GVArrayCommon(); + GVArrayCommon() = default; GVArrayCommon(const GVArrayCommon &other); GVArrayCommon(GVArrayCommon &&other) noexcept; GVArrayCommon(const GVArrayImpl *impl); @@ -186,6 +188,10 @@ class GVArray : public GVArrayCommon { GVArray(const GVArrayImpl *impl); GVArray(std::shared_ptr<const GVArrayImpl> impl); + GVArray(varray_tag::span /* tag */, GSpan span); + GVArray(varray_tag::single_ref /* tag */, const CPPType &type, int64_t size, const void *value); + GVArray(varray_tag::single /* tag */, const CPPType &type, int64_t size, const void *value); + template<typename T> GVArray(const VArray<T> &varray); template<typename T> VArray<T> typed() const; @@ -643,10 +649,18 @@ class GVArrayImpl_For_GSpan : public GVMutableArrayImpl { const int64_t element_size_; public: - GVArrayImpl_For_GSpan(const GMutableSpan span); + GVArrayImpl_For_GSpan(const GMutableSpan span) + : GVMutableArrayImpl(span.type(), span.size()), + data_(span.data()), + element_size_(span.type().size()) + { + } protected: - GVArrayImpl_For_GSpan(const CPPType &type, int64_t size); + GVArrayImpl_For_GSpan(const CPPType &type, int64_t size) + : GVMutableArrayImpl(type, size), element_size_(type.size()) + { + } public: void get(int64_t index, void *r_value) const override; @@ -667,6 +681,61 @@ class GVArrayImpl_For_GSpan : public GVMutableArrayImpl { void *dst) const override; }; +class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan { + public: + using GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan; + + private: + bool may_have_ownership() const override + { + return false; + } +}; + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name #GVArrayImpl_For_SingleValueRef. + * \{ */ + +class GVArrayImpl_For_SingleValueRef : public GVArrayImpl { + protected: + const void *value_ = nullptr; + + public: + GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size, const void *value) + : GVArrayImpl(type, size), value_(value) + { + } + + protected: + GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size) : GVArrayImpl(type, size) + { + } + + void get(const int64_t index, void *r_value) const override; + void get_to_uninitialized(const int64_t index, void *r_value) const override; + bool is_span() const override; + GSpan get_internal_span() const override; + bool is_single() const override; + void get_internal_single(void *r_value) const override; + void materialize(const IndexMask mask, void *dst) const override; + void materialize_to_uninitialized(const IndexMask mask, void *dst) const override; + void materialize_compressed(const IndexMask mask, void *dst) const override; + void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override; +}; + +class GVArrayImpl_For_SingleValueRef_final final : public GVArrayImpl_For_SingleValueRef { + public: + using GVArrayImpl_For_SingleValueRef::GVArrayImpl_For_SingleValueRef; + + private: + bool may_have_ownership() const override + { + return false; + } +}; + /** \} */ /* -------------------------------------------------------------------- */ @@ -809,6 +878,22 @@ inline bool GVArrayCommon::is_empty() const /** \name Inline methods for #GVArray. * \{ */ +inline GVArray::GVArray(varray_tag::span /* tag */, const GSpan span) +{ + /* Use const-cast because the underlying virtual array implementation is shared between const + * and non const data. */ + GMutableSpan mutable_span{span.type(), const_cast<void *>(span.data()), span.size()}; + this->emplace<GVArrayImpl_For_GSpan_final>(mutable_span); +} + +inline GVArray::GVArray(varray_tag::single_ref /* tag */, + const CPPType &type, + const int64_t size, + const void *value) +{ + this->emplace<GVArrayImpl_For_SingleValueRef_final>(type, size, value); +} + namespace detail { template<typename StorageT> constexpr GVArrayAnyExtraInfo GVArrayAnyExtraInfo::get() { diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh index 6efd1d6d769..ab4ca185ddb 100644 --- a/source/blender/blenlib/BLI_virtual_array.hh +++ b/source/blender/blenlib/BLI_virtual_array.hh @@ -872,6 +872,22 @@ template<typename T> class VArrayCommon { template<typename T> class VMutableArray; /** + * Various tags to disambiguate constructors of virtual arrays. + * Generally it is easier to use `VArray::For*` functions to construct virtual arrays, but + * sometimes being able to use the constructor can result in better performance For example, when + * constructing the virtual array directly in a vector. Without the constructor one would have to + * construct the virtual array first and then move it into the vector. + */ +namespace varray_tag { +struct span { +}; +struct single_ref { +}; +struct single { +}; +} // namespace varray_tag + +/** * A #VArray wraps a virtual array implementation and provides easy access to its elements. It can * be copied and moved. While it is relatively small, it should still be passed by reference if * possible (other than e.g. #Span). @@ -892,6 +908,19 @@ template<typename T> class VArray : public VArrayCommon<T> { { } + VArray(varray_tag::span /* tag */, Span<T> span) + { + /* Cast const away, because the virtual array implementation for const and non const spans is + * shared. */ + MutableSpan<T> mutable_span{const_cast<T *>(span.data()), span.size()}; + this->template emplace<VArrayImpl_For_Span_final<T>>(mutable_span); + } + + VArray(varray_tag::single /* tag */, T value, const int64_t size) + { + this->template emplace<VArrayImpl_For_Single<T>>(std::move(value), size); + } + /** * Construct a new virtual array for a custom #VArrayImpl. */ @@ -908,7 +937,7 @@ template<typename T> class VArray : public VArrayCommon<T> { */ static VArray ForSingle(T value, const int64_t size) { - return VArray::For<VArrayImpl_For_Single<T>>(std::move(value), size); + return VArray(varray_tag::single{}, std::move(value), size); } /** @@ -917,10 +946,7 @@ template<typename T> class VArray : public VArrayCommon<T> { */ static VArray ForSpan(Span<T> values) { - /* Cast const away, because the virtual array implementation for const and non const spans is - * shared. */ - MutableSpan<T> span{const_cast<T *>(values.data()), values.size()}; - return VArray::For<VArrayImpl_For_Span_final<T>>(span); + return VArray(varray_tag::span{}, values); } /** diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc index a3a17952a97..a6fbf4bff5b 100644 --- a/source/blender/blenlib/intern/generic_virtual_array.cc +++ b/source/blender/blenlib/intern/generic_virtual_array.cc @@ -85,11 +85,6 @@ bool GVArrayImpl::may_have_ownership() const /** \name #GVMutableArrayImpl * \{ */ -GVMutableArrayImpl::GVMutableArrayImpl(const CPPType &type, const int64_t size) - : GVArrayImpl(type, size) -{ -} - void GVMutableArrayImpl::set_by_copy(const int64_t index, const void *value) { BUFFER_FOR_CPP_TYPE_VALUE(*type_, buffer); @@ -141,18 +136,6 @@ bool GVMutableArrayImpl::try_assign_VMutableArray(void *UNUSED(varray)) const /** \name #GVArrayImpl_For_GSpan * \{ */ -GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const GMutableSpan span) - : GVMutableArrayImpl(span.type(), span.size()), - data_(span.data()), - element_size_(span.type().size()) -{ -} - -GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const CPPType &type, const int64_t size) - : GVMutableArrayImpl(type, size), element_size_(type.size()) -{ -} - void GVArrayImpl_For_GSpan::get(const int64_t index, void *r_value) const { type_->copy_assign(POINTER_OFFSET(data_, element_size_ * index), r_value); @@ -209,17 +192,6 @@ void GVArrayImpl_For_GSpan::materialize_compressed_to_uninitialized(const IndexM type_->copy_construct_compressed(data_, dst, mask); } -class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan { - public: - using GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan; - - private: - bool may_have_ownership() const override - { - return false; - } -}; - /** \} */ /* -------------------------------------------------------------------- */ @@ -227,79 +199,56 @@ class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan { * \{ */ /* Generic virtual array where each element has the same value. The value is not owned. */ -class GVArrayImpl_For_SingleValueRef : public GVArrayImpl { - protected: - const void *value_ = nullptr; - public: - GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size, const void *value) - : GVArrayImpl(type, size), value_(value) - { - } - - protected: - GVArrayImpl_For_SingleValueRef(const CPPType &type, const int64_t size) : GVArrayImpl(type, size) - { - } - - void get(const int64_t UNUSED(index), void *r_value) const override - { - type_->copy_assign(value_, r_value); - } - void get_to_uninitialized(const int64_t UNUSED(index), void *r_value) const override - { - type_->copy_construct(value_, r_value); - } - - bool is_span() const override - { - return size_ == 1; - } - GSpan get_internal_span() const override - { - return GSpan{*type_, value_, 1}; - } - - bool is_single() const override - { - return true; - } - void get_internal_single(void *r_value) const override - { - type_->copy_assign(value_, r_value); - } +void GVArrayImpl_For_SingleValueRef::get(const int64_t UNUSED(index), void *r_value) const +{ + type_->copy_assign(value_, r_value); +} +void GVArrayImpl_For_SingleValueRef::get_to_uninitialized(const int64_t UNUSED(index), + void *r_value) const +{ + type_->copy_construct(value_, r_value); +} - void materialize(const IndexMask mask, void *dst) const override - { - type_->fill_assign_indices(value_, dst, mask); - } +bool GVArrayImpl_For_SingleValueRef::is_span() const +{ + return size_ == 1; +} +GSpan GVArrayImpl_For_SingleValueRef::get_internal_span() const +{ + return GSpan{*type_, value_, 1}; +} - void materialize_to_uninitialized(const IndexMask mask, void *dst) const override - { - type_->fill_construct_indices(value_, dst, mask); - } +bool GVArrayImpl_For_SingleValueRef::is_single() const +{ + return true; +} +void GVArrayImpl_For_SingleValueRef::get_internal_single(void *r_value) const +{ + type_->copy_assign(value_, r_value); +} - void materialize_compressed(const IndexMask mask, void *dst) const override - { - type_->fill_assign_n(value_, dst, mask.size()); - } +void GVArrayImpl_For_SingleValueRef::materialize(const IndexMask mask, void *dst) const +{ + type_->fill_assign_indices(value_, dst, mask); +} - void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override - { - type_->fill_construct_n(value_, dst, mask.size()); - } -}; +void GVArrayImpl_For_SingleValueRef::materialize_to_uninitialized(const IndexMask mask, + void *dst) const +{ + type_->fill_construct_indices(value_, dst, mask); +} -class GVArrayImpl_For_SingleValueRef_final final : public GVArrayImpl_For_SingleValueRef { - public: - using GVArrayImpl_For_SingleValueRef::GVArrayImpl_For_SingleValueRef; +void GVArrayImpl_For_SingleValueRef::materialize_compressed(const IndexMask mask, void *dst) const +{ + type_->fill_assign_n(value_, dst, mask.size()); +} - private: - bool may_have_ownership() const override - { - return false; - } -}; +void GVArrayImpl_For_SingleValueRef::materialize_compressed_to_uninitialized(const IndexMask mask, + void *dst) const +{ + type_->fill_construct_n(value_, dst, mask.size()); +} /** \} */ @@ -529,8 +478,6 @@ class GVArrayImpl_For_SlicedGVArray : public GVArrayImpl { /** \name #GVArrayCommon * \{ */ -GVArrayCommon::GVArrayCommon() = default; - GVArrayCommon::GVArrayCommon(const GVArrayCommon &other) : storage_(other.storage_) { impl_ = this->impl_from_storage(); @@ -672,17 +619,27 @@ GVArray::GVArray(std::shared_ptr<const GVArrayImpl> impl) : GVArrayCommon(std::m { } -GVArray GVArray::ForSingle(const CPPType &type, const int64_t size, const void *value) +GVArray::GVArray(varray_tag::single /* tag */, + const CPPType &type, + int64_t size, + const void *value) { if (type.is_trivial() && type.size() <= 16 && type.alignment() <= 8) { - return GVArray::For<GVArrayImpl_For_SmallTrivialSingleValue<16>>(type, size, value); + this->emplace<GVArrayImpl_For_SmallTrivialSingleValue<16>>(type, size, value); } - return GVArray::For<GVArrayImpl_For_SingleValue>(type, size, value); + else { + this->emplace<GVArrayImpl_For_SingleValue>(type, size, value); + } +} + +GVArray GVArray::ForSingle(const CPPType &type, const int64_t size, const void *value) +{ + return GVArray(varray_tag::single{}, type, size, value); } GVArray GVArray::ForSingleRef(const CPPType &type, const int64_t size, const void *value) { - return GVArray::For<GVArrayImpl_For_SingleValueRef_final>(type, size, value); + return GVArray(varray_tag::single_ref{}, type, size, value); } GVArray GVArray::ForSingleDefault(const CPPType &type, const int64_t size) @@ -692,10 +649,7 @@ GVArray GVArray::ForSingleDefault(const CPPType &type, const int64_t size) GVArray GVArray::ForSpan(GSpan span) { - /* Use const-cast because the underlying virtual array implementation is shared between const - * and non const data. */ - GMutableSpan mutable_span{span.type(), const_cast<void *>(span.data()), span.size()}; - return GVArray::For<GVArrayImpl_For_GSpan_final>(mutable_span); + return GVArray(varray_tag::span{}, span); } class GVArrayImpl_For_GArray : public GVArrayImpl_For_GSpan { diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index 585ada3b2d8..cd56adfe60c 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -347,8 +347,9 @@ static void seq_convert_transform_crop_lb_2(const Scene *scene, } } -static void seq_update_meta_disp_range(Editing *ed) +static void seq_update_meta_disp_range(Scene *scene) { + Editing *ed = SEQ_editing_get(scene); if (ed == NULL) { return; } @@ -356,21 +357,14 @@ static void seq_update_meta_disp_range(Editing *ed) LISTBASE_FOREACH_BACKWARD (MetaStack *, ms, &ed->metastack) { /* Update ms->disp_range from meta. */ if (ms->disp_range[0] == ms->disp_range[1]) { - copy_v2_v2_int(ms->disp_range, &ms->parseq->startdisp); + ms->disp_range[0] = SEQ_time_left_handle_frame_get(ms->parseq); + ms->disp_range[1] = SEQ_time_right_handle_frame_get(ms->parseq); } /* Update meta strip endpoints. */ - SEQ_time_left_handle_frame_set(ms->parseq, ms->disp_range[0]); - SEQ_time_right_handle_frame_set(ms->parseq, ms->disp_range[1]); - SEQ_transform_fix_single_image_seq_offsets(ms->parseq); - - /* Recalculate effects using meta strip. */ - LISTBASE_FOREACH (Sequence *, seq, ms->oldbasep) { - if (seq->seq2) { - seq->start = seq->startdisp = max_ii(seq->seq1->startdisp, seq->seq2->startdisp); - seq->enddisp = min_ii(seq->seq1->enddisp, seq->seq2->enddisp); - } - } + SEQ_time_left_handle_frame_set(scene, ms->parseq, ms->disp_range[0]); + SEQ_time_right_handle_frame_set(scene, ms->parseq, ms->disp_range[1]); + SEQ_transform_fix_single_image_seq_offsets(scene, ms->parseq); /* Ensure that active seqbase points to active meta strip seqbase. */ MetaStack *active_ms = SEQ_meta_stack_active_get(ed); @@ -647,7 +641,7 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) if (!MAIN_VERSION_ATLEAST(bmain, 293, 16)) { LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { - seq_update_meta_disp_range(SEQ_editing_get(scene)); + seq_update_meta_disp_range(scene); } /* Add a separate socket for Grid node X and Y size. */ diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index 83d325e9c40..76d12cc1109 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -405,7 +405,9 @@ static void do_versions_sequencer_speed_effect_recursive(Scene *scene, const Lis v->speed_control_type = SEQ_SPEED_MULTIPLY; v->speed_fader = globalSpeed * ((float)seq->seq1->len / - max_ff((float)(seq->seq1->enddisp - seq->seq1->start), 1.0f)); + max_ff((float)(SEQ_time_right_handle_frame_get(seq->seq1) - + seq->seq1->start), + 1.0f)); } } else if (v->flags & SEQ_SPEED_INTEGRATE) { @@ -1369,6 +1371,250 @@ static void version_liboverride_rnacollections_insertion_animdata(ID *id) } } +static void versioning_replace_legacy_combined_and_separate_color_nodes(bNodeTree *ntree) +{ + /* In geometry nodes, replace shader combine/separate color nodes with function nodes */ + if (ntree->type == NTREE_GEOMETRY) { + version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "R", "Red"); + version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "G", "Green"); + version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "B", "Blue"); + version_node_output_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "Image", "Color"); + + version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "R", "Red"); + version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "G", "Green"); + version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "B", "Blue"); + version_node_input_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "Image", "Color"); + + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + switch (node->type) { + case SH_NODE_COMBRGB_LEGACY: { + node->type = FN_NODE_COMBINE_COLOR; + NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), + __func__); + storage->mode = NODE_COMBSEP_COLOR_RGB; + strcpy(node->idname, "FunctionNodeCombineColor"); + node->storage = storage; + break; + } + case SH_NODE_SEPRGB_LEGACY: { + node->type = FN_NODE_SEPARATE_COLOR; + NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), + __func__); + storage->mode = NODE_COMBSEP_COLOR_RGB; + strcpy(node->idname, "FunctionNodeSeparateColor"); + node->storage = storage; + break; + } + } + } + } + + /* In compositing nodes, replace combine/separate RGBA/HSVA/YCbCrA/YCCA nodes with + * combine/separate color */ + if (ntree->type == NTREE_COMPOSIT) { + version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "R", "Red"); + version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "G", "Green"); + version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "B", "Blue"); + version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "A", "Alpha"); + + version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "H", "Red"); + version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "S", "Green"); + version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "V", "Blue"); + version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "A", "Alpha"); + + version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "Y", "Red"); + version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "Cb", "Green"); + version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "Cr", "Blue"); + version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "A", "Alpha"); + + version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "Y", "Red"); + version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "U", "Green"); + version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "V", "Blue"); + version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "A", "Alpha"); + + version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "R", "Red"); + version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "G", "Green"); + version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "B", "Blue"); + version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "A", "Alpha"); + + version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "H", "Red"); + version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "S", "Green"); + version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "V", "Blue"); + version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "A", "Alpha"); + + version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "Y", "Red"); + version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "Cb", "Green"); + version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "Cr", "Blue"); + version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "A", "Alpha"); + + version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "Y", "Red"); + version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "U", "Green"); + version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "V", "Blue"); + version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "A", "Alpha"); + + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + switch (node->type) { + case CMP_NODE_COMBRGBA_LEGACY: { + node->type = CMP_NODE_COMBINE_COLOR; + NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( + sizeof(NodeCMPCombSepColor), __func__); + storage->mode = CMP_NODE_COMBSEP_COLOR_RGB; + strcpy(node->idname, "CompositorNodeCombineColor"); + node->storage = storage; + break; + } + case CMP_NODE_COMBHSVA_LEGACY: { + node->type = CMP_NODE_COMBINE_COLOR; + NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( + sizeof(NodeCMPCombSepColor), __func__); + storage->mode = CMP_NODE_COMBSEP_COLOR_HSV; + strcpy(node->idname, "CompositorNodeCombineColor"); + node->storage = storage; + break; + } + case CMP_NODE_COMBYCCA_LEGACY: { + node->type = CMP_NODE_COMBINE_COLOR; + NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( + sizeof(NodeCMPCombSepColor), __func__); + storage->mode = CMP_NODE_COMBSEP_COLOR_YCC; + storage->ycc_mode = node->custom1; + strcpy(node->idname, "CompositorNodeCombineColor"); + node->storage = storage; + break; + } + case CMP_NODE_COMBYUVA_LEGACY: { + node->type = CMP_NODE_COMBINE_COLOR; + NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( + sizeof(NodeCMPCombSepColor), __func__); + storage->mode = CMP_NODE_COMBSEP_COLOR_YUV; + strcpy(node->idname, "CompositorNodeCombineColor"); + node->storage = storage; + break; + } + case CMP_NODE_SEPRGBA_LEGACY: { + node->type = CMP_NODE_SEPARATE_COLOR; + NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( + sizeof(NodeCMPCombSepColor), __func__); + storage->mode = CMP_NODE_COMBSEP_COLOR_RGB; + strcpy(node->idname, "CompositorNodeSeparateColor"); + node->storage = storage; + break; + } + case CMP_NODE_SEPHSVA_LEGACY: { + node->type = CMP_NODE_SEPARATE_COLOR; + NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( + sizeof(NodeCMPCombSepColor), __func__); + storage->mode = CMP_NODE_COMBSEP_COLOR_HSV; + strcpy(node->idname, "CompositorNodeSeparateColor"); + node->storage = storage; + break; + } + case CMP_NODE_SEPYCCA_LEGACY: { + node->type = CMP_NODE_SEPARATE_COLOR; + NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( + sizeof(NodeCMPCombSepColor), __func__); + storage->mode = CMP_NODE_COMBSEP_COLOR_YCC; + storage->ycc_mode = node->custom1; + strcpy(node->idname, "CompositorNodeSeparateColor"); + node->storage = storage; + break; + } + case CMP_NODE_SEPYUVA_LEGACY: { + node->type = CMP_NODE_SEPARATE_COLOR; + NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( + sizeof(NodeCMPCombSepColor), __func__); + storage->mode = CMP_NODE_COMBSEP_COLOR_YUV; + strcpy(node->idname, "CompositorNodeSeparateColor"); + node->storage = storage; + break; + } + } + } + } + + /* In texture nodes, replace combine/separate RGBA with combine/separate color */ + if (ntree->type == NTREE_TEXTURE) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + switch (node->type) { + case TEX_NODE_COMPOSE_LEGACY: { + node->type = TEX_NODE_COMBINE_COLOR; + node->custom1 = NODE_COMBSEP_COLOR_RGB; + strcpy(node->idname, "TextureNodeCombineColor"); + break; + } + case TEX_NODE_DECOMPOSE_LEGACY: { + node->type = TEX_NODE_SEPARATE_COLOR; + node->custom1 = NODE_COMBSEP_COLOR_RGB; + strcpy(node->idname, "TextureNodeSeparateColor"); + break; + } + } + } + } + + /* In shader nodes, replace combine/separate RGB/HSV with combine/separate color */ + if (ntree->type == NTREE_SHADER) { + version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "R", "Red"); + version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "G", "Green"); + version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "B", "Blue"); + version_node_output_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "Image", "Color"); + + version_node_input_socket_name(ntree, SH_NODE_COMBHSV_LEGACY, "H", "Red"); + version_node_input_socket_name(ntree, SH_NODE_COMBHSV_LEGACY, "S", "Green"); + version_node_input_socket_name(ntree, SH_NODE_COMBHSV_LEGACY, "V", "Blue"); + + version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "R", "Red"); + version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "G", "Green"); + version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "B", "Blue"); + version_node_input_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "Image", "Color"); + + version_node_output_socket_name(ntree, SH_NODE_SEPHSV_LEGACY, "H", "Red"); + version_node_output_socket_name(ntree, SH_NODE_SEPHSV_LEGACY, "S", "Green"); + version_node_output_socket_name(ntree, SH_NODE_SEPHSV_LEGACY, "V", "Blue"); + + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + switch (node->type) { + case SH_NODE_COMBRGB_LEGACY: { + node->type = SH_NODE_COMBINE_COLOR; + NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), + __func__); + storage->mode = NODE_COMBSEP_COLOR_RGB; + strcpy(node->idname, "ShaderNodeCombineColor"); + node->storage = storage; + break; + } + case SH_NODE_COMBHSV_LEGACY: { + node->type = SH_NODE_COMBINE_COLOR; + NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), + __func__); + storage->mode = NODE_COMBSEP_COLOR_HSV; + strcpy(node->idname, "ShaderNodeCombineColor"); + node->storage = storage; + break; + } + case SH_NODE_SEPRGB_LEGACY: { + node->type = SH_NODE_SEPARATE_COLOR; + NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), + __func__); + storage->mode = NODE_COMBSEP_COLOR_RGB; + strcpy(node->idname, "ShaderNodeSeparateColor"); + node->storage = storage; + break; + } + case SH_NODE_SEPHSV_LEGACY: { + node->type = SH_NODE_SEPARATE_COLOR; + NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), + __func__); + storage->mode = NODE_COMBSEP_COLOR_HSV; + strcpy(node->idname, "ShaderNodeSeparateColor"); + node->storage = storage; + break; + } + } + } + } +} + /* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) { @@ -2487,8 +2733,8 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Rebuild active/render color attribute references. */ if (!MAIN_VERSION_ATLEAST(bmain, 302, 6)) { LISTBASE_FOREACH (Brush *, br, &bmain->brushes) { - /* buggy code in wm_toolsystem broke smear in old files, - reset to defaults */ + /* Buggy code in wm_toolsystem broke smear in old files, + * reset to defaults. */ if (br->sculpt_tool == SCULPT_TOOL_SMEAR) { br->alpha = 1.0f; br->spacing = 5; @@ -2787,248 +3033,8 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) { /* Keep this block, even when empty. */ - /* Replace legacy combine/separate color nodes */ FOREACH_NODETREE_BEGIN (bmain, ntree, id) { - /* In geometry nodes, replace shader combine/separate color nodes with function nodes */ - if (ntree->type == NTREE_GEOMETRY) { - version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "R", "Red"); - version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "G", "Green"); - version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "B", "Blue"); - version_node_output_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "Image", "Color"); - - version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "R", "Red"); - version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "G", "Green"); - version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "B", "Blue"); - version_node_input_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "Image", "Color"); - - LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { - switch (node->type) { - case SH_NODE_COMBRGB_LEGACY: { - node->type = FN_NODE_COMBINE_COLOR; - NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), - __func__); - storage->mode = NODE_COMBSEP_COLOR_RGB; - strcpy(node->idname, "FunctionNodeCombineColor"); - node->storage = storage; - break; - } - case SH_NODE_SEPRGB_LEGACY: { - node->type = FN_NODE_SEPARATE_COLOR; - NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), - __func__); - storage->mode = NODE_COMBSEP_COLOR_RGB; - strcpy(node->idname, "FunctionNodeSeparateColor"); - node->storage = storage; - break; - } - } - } - } - - /* In compositing nodes, replace combine/separate RGBA/HSVA/YCbCrA/YCCA nodes with - * combine/separate color */ - if (ntree->type == NTREE_COMPOSIT) { - version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "R", "Red"); - version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "G", "Green"); - version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "B", "Blue"); - version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "A", "Alpha"); - - version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "H", "Red"); - version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "S", "Green"); - version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "V", "Blue"); - version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "A", "Alpha"); - - version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "Y", "Red"); - version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "Cb", "Green"); - version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "Cr", "Blue"); - version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "A", "Alpha"); - - version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "Y", "Red"); - version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "U", "Green"); - version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "V", "Blue"); - version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "A", "Alpha"); - - version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "R", "Red"); - version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "G", "Green"); - version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "B", "Blue"); - version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "A", "Alpha"); - - version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "H", "Red"); - version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "S", "Green"); - version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "V", "Blue"); - version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "A", "Alpha"); - - version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "Y", "Red"); - version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "Cb", "Green"); - version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "Cr", "Blue"); - version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "A", "Alpha"); - - version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "Y", "Red"); - version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "U", "Green"); - version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "V", "Blue"); - version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "A", "Alpha"); - - LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { - switch (node->type) { - case CMP_NODE_COMBRGBA_LEGACY: { - node->type = CMP_NODE_COMBINE_COLOR; - NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( - sizeof(NodeCMPCombSepColor), __func__); - storage->mode = CMP_NODE_COMBSEP_COLOR_RGB; - strcpy(node->idname, "CompositorNodeCombineColor"); - node->storage = storage; - break; - } - case CMP_NODE_COMBHSVA_LEGACY: { - node->type = CMP_NODE_COMBINE_COLOR; - NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( - sizeof(NodeCMPCombSepColor), __func__); - storage->mode = CMP_NODE_COMBSEP_COLOR_HSV; - strcpy(node->idname, "CompositorNodeCombineColor"); - node->storage = storage; - break; - } - case CMP_NODE_COMBYCCA_LEGACY: { - node->type = CMP_NODE_COMBINE_COLOR; - NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( - sizeof(NodeCMPCombSepColor), __func__); - storage->mode = CMP_NODE_COMBSEP_COLOR_YCC; - storage->ycc_mode = node->custom1; - strcpy(node->idname, "CompositorNodeCombineColor"); - node->storage = storage; - break; - } - case CMP_NODE_COMBYUVA_LEGACY: { - node->type = CMP_NODE_COMBINE_COLOR; - NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( - sizeof(NodeCMPCombSepColor), __func__); - storage->mode = CMP_NODE_COMBSEP_COLOR_YUV; - strcpy(node->idname, "CompositorNodeCombineColor"); - node->storage = storage; - break; - } - case CMP_NODE_SEPRGBA_LEGACY: { - node->type = CMP_NODE_SEPARATE_COLOR; - NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( - sizeof(NodeCMPCombSepColor), __func__); - storage->mode = CMP_NODE_COMBSEP_COLOR_RGB; - strcpy(node->idname, "CompositorNodeSeparateColor"); - node->storage = storage; - break; - } - case CMP_NODE_SEPHSVA_LEGACY: { - node->type = CMP_NODE_SEPARATE_COLOR; - NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( - sizeof(NodeCMPCombSepColor), __func__); - storage->mode = CMP_NODE_COMBSEP_COLOR_HSV; - strcpy(node->idname, "CompositorNodeSeparateColor"); - node->storage = storage; - break; - } - case CMP_NODE_SEPYCCA_LEGACY: { - node->type = CMP_NODE_SEPARATE_COLOR; - NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( - sizeof(NodeCMPCombSepColor), __func__); - storage->mode = CMP_NODE_COMBSEP_COLOR_YCC; - storage->ycc_mode = node->custom1; - strcpy(node->idname, "CompositorNodeSeparateColor"); - node->storage = storage; - break; - } - case CMP_NODE_SEPYUVA_LEGACY: { - node->type = CMP_NODE_SEPARATE_COLOR; - NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN( - sizeof(NodeCMPCombSepColor), __func__); - storage->mode = CMP_NODE_COMBSEP_COLOR_YUV; - strcpy(node->idname, "CompositorNodeSeparateColor"); - node->storage = storage; - break; - } - } - } - } - - /* In texture nodes, replace combine/separate RGBA with combine/separate color */ - if (ntree->type == NTREE_TEXTURE) { - LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { - switch (node->type) { - case TEX_NODE_COMPOSE_LEGACY: { - node->type = TEX_NODE_COMBINE_COLOR; - node->custom1 = NODE_COMBSEP_COLOR_RGB; - strcpy(node->idname, "TextureNodeCombineColor"); - break; - } - case TEX_NODE_DECOMPOSE_LEGACY: { - node->type = TEX_NODE_SEPARATE_COLOR; - node->custom1 = NODE_COMBSEP_COLOR_RGB; - strcpy(node->idname, "TextureNodeSeparateColor"); - break; - } - } - } - } - - /* In shader nodes, replace combine/separate RGB/HSV with combine/separate color */ - if (ntree->type == NTREE_SHADER) { - version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "R", "Red"); - version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "G", "Green"); - version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "B", "Blue"); - version_node_output_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "Image", "Color"); - - version_node_input_socket_name(ntree, SH_NODE_COMBHSV_LEGACY, "H", "Red"); - version_node_input_socket_name(ntree, SH_NODE_COMBHSV_LEGACY, "S", "Green"); - version_node_input_socket_name(ntree, SH_NODE_COMBHSV_LEGACY, "V", "Blue"); - - version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "R", "Red"); - version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "G", "Green"); - version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "B", "Blue"); - version_node_input_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "Image", "Color"); - - version_node_output_socket_name(ntree, SH_NODE_SEPHSV_LEGACY, "H", "Red"); - version_node_output_socket_name(ntree, SH_NODE_SEPHSV_LEGACY, "S", "Green"); - version_node_output_socket_name(ntree, SH_NODE_SEPHSV_LEGACY, "V", "Blue"); - - LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { - switch (node->type) { - case SH_NODE_COMBRGB_LEGACY: { - node->type = SH_NODE_COMBINE_COLOR; - NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), - __func__); - storage->mode = NODE_COMBSEP_COLOR_RGB; - strcpy(node->idname, "ShaderNodeCombineColor"); - node->storage = storage; - break; - } - case SH_NODE_COMBHSV_LEGACY: { - node->type = SH_NODE_COMBINE_COLOR; - NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), - __func__); - storage->mode = NODE_COMBSEP_COLOR_HSV; - strcpy(node->idname, "ShaderNodeCombineColor"); - node->storage = storage; - break; - } - case SH_NODE_SEPRGB_LEGACY: { - node->type = SH_NODE_SEPARATE_COLOR; - NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), - __func__); - storage->mode = NODE_COMBSEP_COLOR_RGB; - strcpy(node->idname, "ShaderNodeSeparateColor"); - node->storage = storage; - break; - } - case SH_NODE_SEPHSV_LEGACY: { - node->type = SH_NODE_SEPARATE_COLOR; - NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor), - __func__); - storage->mode = NODE_COMBSEP_COLOR_HSV; - strcpy(node->idname, "ShaderNodeSeparateColor"); - node->storage = storage; - break; - } - } - } - } + versioning_replace_legacy_combined_and_separate_color_nodes(ntree); } FOREACH_NODETREE_END; diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index cb930d7facb..bd3d2d135f1 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -60,8 +60,11 @@ void BM_edges_from_verts_ensure(BMesh *bm, BMEdge **edge_arr, BMVert **vert_arr, } /* prototypes */ -static void bm_loop_attrs_copy( - BMesh *bm_src, BMesh *bm_dst, const BMLoop *l_src, BMLoop *l_dst, CustomDataMask mask_exclude); +static void bm_loop_attrs_copy(BMesh *bm_src, + BMesh *bm_dst, + const BMLoop *l_src, + BMLoop *l_dst, + eCustomDataMask mask_exclude); BMFace *BM_face_create_quad_tri(BMesh *bm, BMVert *v1, @@ -321,7 +324,7 @@ void BM_verts_sort_radial_plane(BMVert **vert_arr, int len) /*************************************************************/ static void bm_vert_attrs_copy( - BMesh *bm_src, BMesh *bm_dst, const BMVert *v_src, BMVert *v_dst, CustomDataMask mask_exclude) + BMesh *bm_src, BMesh *bm_dst, const BMVert *v_src, BMVert *v_dst, eCustomDataMask mask_exclude) { if ((bm_src == bm_dst) && (v_src == v_dst)) { BLI_assert_msg(0, "BMVert: source and target match"); @@ -336,7 +339,7 @@ static void bm_vert_attrs_copy( } static void bm_edge_attrs_copy( - BMesh *bm_src, BMesh *bm_dst, const BMEdge *e_src, BMEdge *e_dst, CustomDataMask mask_exclude) + BMesh *bm_src, BMesh *bm_dst, const BMEdge *e_src, BMEdge *e_dst, eCustomDataMask mask_exclude) { if ((bm_src == bm_dst) && (e_src == e_dst)) { BLI_assert_msg(0, "BMEdge: source and target match"); @@ -348,7 +351,7 @@ static void bm_edge_attrs_copy( } static void bm_loop_attrs_copy( - BMesh *bm_src, BMesh *bm_dst, const BMLoop *l_src, BMLoop *l_dst, CustomDataMask mask_exclude) + BMesh *bm_src, BMesh *bm_dst, const BMLoop *l_src, BMLoop *l_dst, eCustomDataMask mask_exclude) { if ((bm_src == bm_dst) && (l_src == l_dst)) { BLI_assert_msg(0, "BMLoop: source and target match"); @@ -360,7 +363,7 @@ static void bm_loop_attrs_copy( } static void bm_face_attrs_copy( - BMesh *bm_src, BMesh *bm_dst, const BMFace *f_src, BMFace *f_dst, CustomDataMask mask_exclude) + BMesh *bm_src, BMesh *bm_dst, const BMFace *f_src, BMFace *f_dst, eCustomDataMask mask_exclude) { if ((bm_src == bm_dst) && (f_src == f_dst)) { BLI_assert_msg(0, "BMFace: source and target match"); diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 208c9e6c816..038e4202ddd 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -959,7 +959,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh me->totloop = bm->totloop; me->totpoly = bm->totface; /* Will be overwritten with a valid value if 'dotess' is set, otherwise we - * end up with 'me->totface' and me->mface == nullptr which can crash T28625. */ + * end up with 'me->totface' and `me->mface == nullptr` which can crash T28625. */ me->totface = 0; me->act_face = -1; diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index aa7f0f511ec..1339efb3057 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -145,7 +145,7 @@ static bool bm_edge_is_contiguous_loop_cd_all(const BMEdge *e, } static bool bm_edge_delimit_cdata(CustomData *ldata, - CustomDataType type, + eCustomDataType type, struct DelimitData_CD *r_delim_cd) { const int layer_len = CustomData_number_of_layers(ldata, type); diff --git a/source/blender/datatoc/datatoc_icon.py b/source/blender/datatoc/datatoc_icon.py index cce464dbc41..7373df71318 100755 --- a/source/blender/datatoc/datatoc_icon.py +++ b/source/blender/datatoc/datatoc_icon.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0-or-later - -# <pep8 compliant> _IS_BIG_ENDIAN = (__import__("sys").byteorder != 'little') diff --git a/source/blender/datatoc/datatoc_icon_split.py b/source/blender/datatoc/datatoc_icon_split.py index fcfd63f8707..8edafeda328 100755 --- a/source/blender/datatoc/datatoc_icon_split.py +++ b/source/blender/datatoc/datatoc_icon_split.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-or-later -# <pep8 compliant> - """ This script dices up PNG into small files to store in version control. diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index 56117a00b73..a3cd821e82f 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -54,9 +54,9 @@ bool deg_check_base_in_depsgraph(const Depsgraph *graph, Base *base) return id_node->has_base; } -/******************************************************************************* - * Base class for builders. - */ +/* -------------------------------------------------------------------- */ +/** \name Base Class for Builders + * \{ */ DepsgraphBuilder::DepsgraphBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache) : bmain_(bmain), graph_(graph), cache_(cache) @@ -120,9 +120,11 @@ bool DepsgraphBuilder::check_pchan_has_bbone_segments(Object *object, const char return check_pchan_has_bbone_segments(object, pchan); } -/******************************************************************************* - * Builder finalizer. - */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Builder Finalizer. + * \{ */ namespace { @@ -137,7 +139,7 @@ void deg_graph_build_flush_visibility(Depsgraph *graph) for (ComponentNode *comp_node : id_node->components.values()) { comp_node->affects_directly_visible |= id_node->is_directly_visible; - /* Enforce "visibility" of the syncronization component. + /* Enforce "visibility" of the synchronization component. * * This component is never connected to other ID nodes, and hence can not be handled in the * same way as other components needed for evaluation. It is only needed for proper @@ -213,7 +215,7 @@ void deg_graph_build_flush_visibility(Depsgraph *graph) void deg_graph_build_finalize(Main *bmain, Depsgraph *graph) { - /* Make sure dependencies of visible ID datablocks are visible. */ + /* Make sure dependencies of visible ID data-blocks are visible. */ deg_graph_build_flush_visibility(graph); deg_graph_remove_unused_noops(graph); @@ -248,4 +250,6 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph) } } +/** \} */ + } // namespace blender::deg diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index ae159373efd..c16325b7299 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1137,6 +1137,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id, /* Add dependencies for each constraint in turn. */ for (bConstraint *con = (bConstraint *)constraints->first; con; con = con->next) { const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); + ListBase targets = {nullptr, nullptr}; /* Invalid constraint type. */ if (cti == nullptr) { continue; @@ -1188,9 +1189,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id, add_relation(cache_key, constraint_op_key, cti->name); } } - else if (cti->get_constraint_targets) { - ListBase targets = {nullptr, nullptr}; - cti->get_constraint_targets(con, &targets); + else if (BKE_constraint_targets_get(con, &targets)) { LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) { if (ct->tar == nullptr) { continue; @@ -1300,9 +1299,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id, add_relation(target_transform_key, constraint_op_key, cti->name); } } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, true); - } + BKE_constraint_targets_flush(con, &targets, true); } } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index d2a89576022..e6c8558bb37 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -452,108 +452,113 @@ set(GLSL_SRC engines/select/shaders/select_id_vert.glsl engines/select/shaders/select_id_frag.glsl - engines/basic/shaders/conservative_depth_geom.glsl - engines/basic/shaders/depth_vert.glsl - engines/basic/shaders/depth_pointcloud_vert.glsl - engines/basic/shaders/depth_frag.glsl - - engines/overlay/shaders/common_overlay_lib.glsl - engines/overlay/shaders/antialiasing_frag.glsl - engines/overlay/shaders/armature_dof_vert.glsl - engines/overlay/shaders/armature_dof_solid_frag.glsl - engines/overlay/shaders/armature_envelope_outline_vert.glsl - engines/overlay/shaders/armature_envelope_solid_frag.glsl - engines/overlay/shaders/armature_envelope_solid_vert.glsl - engines/overlay/shaders/armature_shape_outline_geom.glsl - engines/overlay/shaders/armature_shape_outline_vert.glsl - engines/overlay/shaders/armature_shape_solid_frag.glsl - engines/overlay/shaders/armature_shape_solid_vert.glsl - engines/overlay/shaders/armature_shape_wire_vert.glsl - engines/overlay/shaders/armature_sphere_outline_vert.glsl - engines/overlay/shaders/armature_sphere_solid_frag.glsl - engines/overlay/shaders/armature_sphere_solid_vert.glsl - engines/overlay/shaders/armature_stick_frag.glsl - engines/overlay/shaders/armature_stick_vert.glsl - engines/overlay/shaders/armature_wire_frag.glsl - engines/overlay/shaders/armature_wire_vert.glsl - engines/overlay/shaders/background_frag.glsl - engines/overlay/shaders/clipbound_vert.glsl - engines/overlay/shaders/depth_only_vert.glsl - engines/overlay/shaders/edit_curve_handle_geom.glsl - engines/overlay/shaders/edit_curve_handle_vert.glsl - engines/overlay/shaders/edit_curve_point_vert.glsl - engines/overlay/shaders/edit_curve_wire_vert.glsl - engines/overlay/shaders/edit_gpencil_canvas_vert.glsl - engines/overlay/shaders/edit_gpencil_guide_vert.glsl - engines/overlay/shaders/edit_gpencil_vert.glsl - engines/overlay/shaders/edit_lattice_point_vert.glsl - engines/overlay/shaders/edit_lattice_wire_vert.glsl - engines/overlay/shaders/edit_mesh_common_lib.glsl - engines/overlay/shaders/edit_mesh_frag.glsl - engines/overlay/shaders/edit_mesh_geom.glsl - engines/overlay/shaders/edit_mesh_normal_vert.glsl - engines/overlay/shaders/edit_mesh_analysis_frag.glsl - engines/overlay/shaders/edit_mesh_analysis_vert.glsl - engines/overlay/shaders/edit_mesh_skin_root_vert.glsl - engines/overlay/shaders/edit_mesh_vert.glsl - engines/overlay/shaders/edit_particle_strand_vert.glsl - engines/overlay/shaders/edit_particle_point_vert.glsl - engines/overlay/shaders/edit_uv_edges_vert.glsl - engines/overlay/shaders/edit_uv_edges_geom.glsl - engines/overlay/shaders/edit_uv_edges_frag.glsl - engines/overlay/shaders/edit_uv_verts_vert.glsl - engines/overlay/shaders/edit_uv_verts_frag.glsl - engines/overlay/shaders/edit_uv_faces_vert.glsl - engines/overlay/shaders/edit_uv_face_dots_vert.glsl - engines/overlay/shaders/edit_uv_image_vert.glsl - engines/overlay/shaders/edit_uv_image_mask_frag.glsl - engines/overlay/shaders/edit_uv_stretching_vert.glsl - engines/overlay/shaders/edit_uv_tiled_image_borders_vert.glsl - engines/overlay/shaders/extra_frag.glsl - engines/overlay/shaders/extra_vert.glsl - engines/overlay/shaders/extra_groundline_vert.glsl - engines/overlay/shaders/extra_lightprobe_grid_vert.glsl - engines/overlay/shaders/extra_loose_point_frag.glsl - engines/overlay/shaders/extra_loose_point_vert.glsl - engines/overlay/shaders/extra_point_vert.glsl - engines/overlay/shaders/extra_wire_frag.glsl - engines/overlay/shaders/extra_wire_vert.glsl - engines/overlay/shaders/facing_frag.glsl - engines/overlay/shaders/facing_vert.glsl - engines/overlay/shaders/grid_background_frag.glsl - engines/overlay/shaders/grid_frag.glsl - engines/overlay/shaders/grid_vert.glsl - engines/overlay/shaders/image_vert.glsl - engines/overlay/shaders/image_frag.glsl - engines/overlay/shaders/motion_path_line_frag.glsl - engines/overlay/shaders/motion_path_line_geom.glsl - engines/overlay/shaders/motion_path_line_vert.glsl - engines/overlay/shaders/motion_path_point_vert.glsl - engines/overlay/shaders/outline_detect_frag.glsl - engines/overlay/shaders/outline_prepass_frag.glsl - engines/overlay/shaders/outline_prepass_gpencil_frag.glsl - engines/overlay/shaders/outline_prepass_geom.glsl - engines/overlay/shaders/outline_prepass_gpencil_vert.glsl - engines/overlay/shaders/outline_prepass_pointcloud_vert.glsl - engines/overlay/shaders/outline_prepass_vert.glsl - engines/overlay/shaders/paint_face_vert.glsl - engines/overlay/shaders/paint_point_vert.glsl - engines/overlay/shaders/paint_texture_frag.glsl - engines/overlay/shaders/paint_texture_vert.glsl - engines/overlay/shaders/paint_vertcol_frag.glsl - engines/overlay/shaders/paint_vertcol_vert.glsl - engines/overlay/shaders/paint_weight_frag.glsl - engines/overlay/shaders/paint_weight_vert.glsl - engines/overlay/shaders/paint_wire_vert.glsl - engines/overlay/shaders/particle_vert.glsl - engines/overlay/shaders/particle_frag.glsl - engines/overlay/shaders/sculpt_mask_vert.glsl - engines/overlay/shaders/sculpt_mask_frag.glsl - engines/overlay/shaders/volume_velocity_vert.glsl - engines/overlay/shaders/volume_gridlines_vert.glsl - engines/overlay/shaders/wireframe_vert.glsl - engines/overlay/shaders/wireframe_frag.glsl - engines/overlay/shaders/xray_fade_frag.glsl + engines/basic/shaders/basic_conservative_depth_geom.glsl + engines/basic/shaders/basic_depth_vert.glsl + engines/basic/shaders/basic_depth_pointcloud_vert.glsl + engines/basic/shaders/basic_depth_frag.glsl + + engines/overlay/shaders/overlay_antialiasing_frag.glsl + engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl + engines/overlay/shaders/overlay_armature_dof_vert.glsl + engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl + engines/overlay/shaders/overlay_armature_envelope_solid_frag.glsl + engines/overlay/shaders/overlay_armature_envelope_solid_vert.glsl + engines/overlay/shaders/overlay_armature_shape_outline_geom.glsl + engines/overlay/shaders/overlay_armature_shape_outline_vert.glsl + engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl + engines/overlay/shaders/overlay_armature_shape_solid_vert.glsl + engines/overlay/shaders/overlay_armature_shape_wire_vert.glsl + engines/overlay/shaders/overlay_armature_sphere_outline_vert.glsl + engines/overlay/shaders/overlay_armature_sphere_solid_frag.glsl + engines/overlay/shaders/overlay_armature_sphere_solid_vert.glsl + engines/overlay/shaders/overlay_armature_stick_frag.glsl + engines/overlay/shaders/overlay_armature_stick_vert.glsl + engines/overlay/shaders/overlay_armature_wire_frag.glsl + engines/overlay/shaders/overlay_armature_wire_vert.glsl + engines/overlay/shaders/overlay_background_frag.glsl + engines/overlay/shaders/overlay_clipbound_vert.glsl + engines/overlay/shaders/overlay_common_lib.glsl + engines/overlay/shaders/overlay_depth_only_frag.glsl + engines/overlay/shaders/overlay_depth_only_vert.glsl + engines/overlay/shaders/overlay_edit_curve_handle_geom.glsl + engines/overlay/shaders/overlay_edit_curve_handle_vert.glsl + engines/overlay/shaders/overlay_edit_curve_point_vert.glsl + engines/overlay/shaders/overlay_edit_curve_wire_vert.glsl + engines/overlay/shaders/overlay_edit_gpencil_canvas_vert.glsl + engines/overlay/shaders/overlay_edit_gpencil_guide_vert.glsl + engines/overlay/shaders/overlay_edit_gpencil_vert.glsl + engines/overlay/shaders/overlay_edit_lattice_point_vert.glsl + engines/overlay/shaders/overlay_edit_lattice_wire_vert.glsl + engines/overlay/shaders/overlay_edit_mesh_analysis_frag.glsl + engines/overlay/shaders/overlay_edit_mesh_analysis_vert.glsl + engines/overlay/shaders/overlay_edit_mesh_common_lib.glsl + engines/overlay/shaders/overlay_edit_mesh_frag.glsl + engines/overlay/shaders/overlay_edit_mesh_geom.glsl + engines/overlay/shaders/overlay_edit_mesh_normal_vert.glsl + engines/overlay/shaders/overlay_edit_mesh_skin_root_vert.glsl + engines/overlay/shaders/overlay_edit_mesh_vert.glsl + engines/overlay/shaders/overlay_edit_particle_point_vert.glsl + engines/overlay/shaders/overlay_edit_particle_strand_vert.glsl + engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl + engines/overlay/shaders/overlay_edit_uv_edges_geom.glsl + engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl + engines/overlay/shaders/overlay_edit_uv_face_dots_vert.glsl + engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl + engines/overlay/shaders/overlay_edit_uv_image_mask_frag.glsl + engines/overlay/shaders/overlay_edit_uv_image_vert.glsl + engines/overlay/shaders/overlay_edit_uv_stretching_vert.glsl + engines/overlay/shaders/overlay_edit_uv_tiled_image_borders_vert.glsl + engines/overlay/shaders/overlay_edit_uv_verts_frag.glsl + engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl + engines/overlay/shaders/overlay_extra_frag.glsl + engines/overlay/shaders/overlay_extra_groundline_vert.glsl + engines/overlay/shaders/overlay_extra_lightprobe_grid_vert.glsl + engines/overlay/shaders/overlay_extra_loose_point_frag.glsl + engines/overlay/shaders/overlay_extra_loose_point_vert.glsl + engines/overlay/shaders/overlay_extra_point_vert.glsl + engines/overlay/shaders/overlay_extra_vert.glsl + engines/overlay/shaders/overlay_extra_wire_frag.glsl + engines/overlay/shaders/overlay_extra_wire_vert.glsl + engines/overlay/shaders/overlay_facing_frag.glsl + engines/overlay/shaders/overlay_facing_vert.glsl + engines/overlay/shaders/overlay_grid_background_frag.glsl + engines/overlay/shaders/overlay_grid_frag.glsl + engines/overlay/shaders/overlay_grid_vert.glsl + engines/overlay/shaders/overlay_image_frag.glsl + engines/overlay/shaders/overlay_image_vert.glsl + engines/overlay/shaders/overlay_motion_path_line_frag.glsl + engines/overlay/shaders/overlay_motion_path_line_geom.glsl + engines/overlay/shaders/overlay_motion_path_line_vert.glsl + engines/overlay/shaders/overlay_motion_path_point_vert.glsl + engines/overlay/shaders/overlay_outline_detect_frag.glsl + engines/overlay/shaders/overlay_outline_prepass_frag.glsl + engines/overlay/shaders/overlay_outline_prepass_geom.glsl + engines/overlay/shaders/overlay_outline_prepass_gpencil_frag.glsl + engines/overlay/shaders/overlay_outline_prepass_gpencil_vert.glsl + engines/overlay/shaders/overlay_outline_prepass_pointcloud_vert.glsl + engines/overlay/shaders/overlay_outline_prepass_vert.glsl + engines/overlay/shaders/overlay_paint_face_vert.glsl + engines/overlay/shaders/overlay_paint_point_vert.glsl + engines/overlay/shaders/overlay_paint_texture_frag.glsl + engines/overlay/shaders/overlay_paint_texture_vert.glsl + engines/overlay/shaders/overlay_paint_vertcol_frag.glsl + engines/overlay/shaders/overlay_paint_vertcol_vert.glsl + engines/overlay/shaders/overlay_paint_weight_frag.glsl + engines/overlay/shaders/overlay_paint_weight_vert.glsl + engines/overlay/shaders/overlay_paint_wire_vert.glsl + engines/overlay/shaders/overlay_particle_frag.glsl + engines/overlay/shaders/overlay_particle_vert.glsl + engines/overlay/shaders/overlay_point_varying_color_frag.glsl + engines/overlay/shaders/overlay_point_varying_color_varying_outline_aa_frag.glsl + engines/overlay/shaders/overlay_sculpt_mask_frag.glsl + engines/overlay/shaders/overlay_sculpt_mask_vert.glsl + engines/overlay/shaders/overlay_uniform_color_frag.glsl + engines/overlay/shaders/overlay_varying_color.glsl + engines/overlay/shaders/overlay_volume_gridlines_vert.glsl + engines/overlay/shaders/overlay_volume_velocity_vert.glsl + engines/overlay/shaders/overlay_wireframe_frag.glsl + engines/overlay/shaders/overlay_wireframe_vert.glsl + engines/overlay/shaders/overlay_xray_fade_frag.glsl engines/overlay/overlay_shader_shared.h diff --git a/source/blender/draw/engines/basic/basic_shader.c b/source/blender/draw/engines/basic/basic_shader.c index d7a8f23e3b3..3d40c627fff 100644 --- a/source/blender/draw/engines/basic/basic_shader.c +++ b/source/blender/draw/engines/basic/basic_shader.c @@ -11,9 +11,9 @@ #include "basic_private.h" -extern char datatoc_depth_frag_glsl[]; -extern char datatoc_depth_vert_glsl[]; -extern char datatoc_conservative_depth_geom_glsl[]; +extern char datatoc_basic_depth_frag_glsl[]; +extern char datatoc_basic_depth_vert_glsl[]; +extern char datatoc_basic_conservative_depth_geom_glsl[]; extern char datatoc_common_view_lib_glsl[]; extern char datatoc_common_pointcloud_lib_glsl[]; diff --git a/source/blender/draw/engines/basic/shaders/conservative_depth_geom.glsl b/source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl index d478f37691e..d478f37691e 100644 --- a/source/blender/draw/engines/basic/shaders/conservative_depth_geom.glsl +++ b/source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl diff --git a/source/blender/draw/engines/basic/shaders/depth_frag.glsl b/source/blender/draw/engines/basic/shaders/basic_depth_frag.glsl index ff4a015c335..ff4a015c335 100644 --- a/source/blender/draw/engines/basic/shaders/depth_frag.glsl +++ b/source/blender/draw/engines/basic/shaders/basic_depth_frag.glsl diff --git a/source/blender/draw/engines/basic/shaders/depth_pointcloud_vert.glsl b/source/blender/draw/engines/basic/shaders/basic_depth_pointcloud_vert.glsl index b82edc61cee..b82edc61cee 100644 --- a/source/blender/draw/engines/basic/shaders/depth_pointcloud_vert.glsl +++ b/source/blender/draw/engines/basic/shaders/basic_depth_pointcloud_vert.glsl diff --git a/source/blender/draw/engines/basic/shaders/depth_vert.glsl b/source/blender/draw/engines/basic/shaders/basic_depth_vert.glsl index 7046979cf97..7046979cf97 100644 --- a/source/blender/draw/engines/basic/shaders/depth_vert.glsl +++ b/source/blender/draw/engines/basic/shaders/basic_depth_vert.glsl diff --git a/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh b/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh index 9914d264c63..bae50eb48fa 100644 --- a/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh +++ b/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh @@ -10,7 +10,7 @@ GPU_SHADER_CREATE_INFO(basic_conservative) .geometry_layout(PrimitiveIn::TRIANGLES, PrimitiveOut::TRIANGLE_STRIP, 3) - .geometry_source("conservative_depth_geom.glsl"); + .geometry_source("basic_conservative_depth_geom.glsl"); /** \} */ @@ -20,11 +20,11 @@ GPU_SHADER_CREATE_INFO(basic_conservative) GPU_SHADER_CREATE_INFO(basic_mesh) .vertex_in(0, Type::VEC3, "pos") - .vertex_source("depth_vert.glsl") + .vertex_source("basic_depth_vert.glsl") .additional_info("draw_mesh"); GPU_SHADER_CREATE_INFO(basic_pointcloud) - .vertex_source("depth_pointcloud_vert.glsl") + .vertex_source("basic_depth_pointcloud_vert.glsl") .additional_info("draw_pointcloud"); /** \} */ @@ -54,7 +54,7 @@ GPU_SHADER_CREATE_INFO(basic_pointcloud) /** \name Depth shader types. * \{ */ -GPU_SHADER_CREATE_INFO(basic_depth).fragment_source("depth_frag.glsl"); +GPU_SHADER_CREATE_INFO(basic_depth).fragment_source("basic_depth_frag.glsl"); BASIC_OBTYPE_VARIATIONS(basic_depth, "basic_depth"); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 0a7c8e185c4..a978d6fe75e 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -671,7 +671,7 @@ typedef struct EEVEE_HairMotionData { /** Allocator will alloc enough slot for all particle systems. Or 1 if it's a curves object. */ int psys_len; struct { - /* The vbos and textures are not owned. */ + /* The VBO's and textures are not owned. */ EEVEE_HairMotionStepData step_data[2]; /* Data for time = t +/- step. */ } psys[0]; } EEVEE_HairMotionData; diff --git a/source/blender/draw/engines/eevee_next/eevee_defines.hh b/source/blender/draw/engines/eevee_next/eevee_defines.hh index 7141928a20d..f75ebd2bd13 100644 --- a/source/blender/draw/engines/eevee_next/eevee_defines.hh +++ b/source/blender/draw/engines/eevee_next/eevee_defines.hh @@ -12,7 +12,7 @@ #pragma once /** - Number of items in a culling batch. Needs to be Power of 2. Must be <= to 65536. + * Number of items in a culling batch. Needs to be Power of 2. Must be <= to 65536. * Current limiting factor is the sorting phase which is single pass and only sort within a * thread-group which maximum size is 1024. */ diff --git a/source/blender/draw/engines/eevee_next/eevee_velocity.cc b/source/blender/draw/engines/eevee_next/eevee_velocity.cc index 9f8dce43910..ceae9df44d0 100644 --- a/source/blender/draw/engines/eevee_next/eevee_velocity.cc +++ b/source/blender/draw/engines/eevee_next/eevee_velocity.cc @@ -185,7 +185,7 @@ void VelocityModule::step_swap() dst_ofs += src_len; } /* TODO(@fclem): Fail gracefully (disable motion blur + warning print) if - `tot_len * sizeof(float4)` is greater than max SSBO size. */ + * `tot_len * sizeof(float4)` is greater than max SSBO size. */ geometry_steps[step_]->resize(max_ii(16, dst_ofs)); for (VelocityGeometryData &geom : geometry_map.values()) { diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl index 1b113e529b6..fafea1e576e 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl @@ -132,7 +132,9 @@ int curves_attribute_element_id() { int id = interp.curves_strand_id; if (drw_curves.is_point_attribute[g_curves_attr_id] != 0) { +# ifdef COMMON_HAIR_LIB id = hair_get_base_id(); +# endif } g_curves_attr_id += 1; diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh index 49250b5741e..a944bea402e 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh @@ -39,7 +39,10 @@ GPU_SHADER_CREATE_INFO(eevee_geom_curves) .additional_info("eevee_shared") .define("MAT_GEOM_CURVES") .vertex_source("eevee_geom_curves_vert.glsl") - .additional_info("draw_hair", "draw_resource_id_varying", "draw_resource_handle"); + .additional_info("draw_hair", + "draw_curves_infos", + "draw_resource_id_varying", + "draw_resource_handle"); GPU_SHADER_CREATE_INFO(eevee_geom_world) .additional_info("eevee_shared") @@ -166,7 +169,7 @@ GPU_SHADER_CREATE_INFO(eevee_material_stub).define("EEVEE_MATERIAL_STUBS"); # define EEVEE_MAT_GEOM_VARIATIONS(prefix, ...) \ EEVEE_MAT_FINAL_VARIATION(prefix##_world, "eevee_geom_world", __VA_ARGS__) \ EEVEE_MAT_FINAL_VARIATION(prefix##_gpencil, "eevee_geom_gpencil", __VA_ARGS__) \ - EEVEE_MAT_FINAL_VARIATION(prefix##_hair, "eevee_geom_curves", __VA_ARGS__) \ + EEVEE_MAT_FINAL_VARIATION(prefix##_curves, "eevee_geom_curves", __VA_ARGS__) \ EEVEE_MAT_FINAL_VARIATION(prefix##_mesh, "eevee_geom_mesh", __VA_ARGS__) # define EEVEE_MAT_PIPE_VARIATIONS(name, ...) \ diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c index 9f2f2b4b23d..b9c09e2bc4f 100644 --- a/source/blender/draw/engines/external/external_engine.c +++ b/source/blender/draw/engines/external/external_engine.c @@ -36,8 +36,8 @@ #define EXTERNAL_ENGINE "BLENDER_EXTERNAL" -extern char datatoc_depth_frag_glsl[]; -extern char datatoc_depth_vert_glsl[]; +extern char datatoc_basic_depth_frag_glsl[]; +extern char datatoc_basic_depth_vert_glsl[]; extern char datatoc_common_view_lib_glsl[]; diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c index 5d8ba06e181..f875254a685 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.c +++ b/source/blender/draw/engines/overlay/overlay_extra.c @@ -1310,13 +1310,11 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb, } else { const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon); + ListBase targets = {NULL, NULL}; - if ((cti && cti->get_constraint_targets) && (curcon->ui_expand_flag & (1 << 0))) { - ListBase targets = {NULL, NULL}; + if ((curcon->ui_expand_flag & (1 << 0)) && BKE_constraint_targets_get(curcon, &targets)) { bConstraintTarget *ct; - cti->get_constraint_targets(curcon, &targets); - for (ct = targets.first; ct; ct = ct->next) { /* calculate target's matrix */ if (cti->get_target_matrix) { @@ -1328,9 +1326,7 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb, OVERLAY_extra_line_dashed(cb, ct->matrix[3], ob->obmat[3], constraint_color); } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(curcon, &targets, 1); - } + BKE_constraint_targets_flush(curcon, &targets, 1); } } } diff --git a/source/blender/draw/engines/overlay/shaders/infos/antialiasing_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_antialiasing_info.hh index fe67dd473b7..0dba8b54e35 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/antialiasing_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_antialiasing_info.hh @@ -9,7 +9,7 @@ GPU_SHADER_CREATE_INFO(overlay_antialiasing) .sampler(2, ImageType::FLOAT_2D, "lineTex") .push_constant(Type::BOOL, "doSmoothLines") .fragment_out(0, Type::VEC4, "fragColor") - .fragment_source("antialiasing_frag.glsl") + .fragment_source("overlay_antialiasing_frag.glsl") .additional_info("draw_fullscreen", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_xray_fade) @@ -18,5 +18,5 @@ GPU_SHADER_CREATE_INFO(overlay_xray_fade) .sampler(1, ImageType::DEPTH_2D, "xrayDepthTex") .push_constant(Type::FLOAT, "opacity") .fragment_out(0, Type::VEC4, "fragColor") - .fragment_source("xray_fade_frag.glsl") + .fragment_source("overlay_xray_fade_frag.glsl") .additional_info("draw_fullscreen"); diff --git a/source/blender/draw/engines/overlay/shaders/infos/armature_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh index d89272a50cf..9f2acceed97 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/armature_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh @@ -25,8 +25,8 @@ GPU_SHADER_CREATE_INFO(overlay_armature_sphere_outline) /* Per instance. */ .vertex_in(1, Type::MAT4, "inst_obmat") .vertex_out(overlay_armature_wire_iface) - .vertex_source("armature_sphere_outline_vert.glsl") - .fragment_source("armature_wire_frag.glsl") + .vertex_source("overlay_armature_sphere_outline_vert.glsl") + .fragment_source("overlay_armature_wire_frag.glsl") .additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_armature_sphere_outline_clipped) @@ -47,8 +47,8 @@ GPU_SHADER_CREATE_INFO(overlay_armature_sphere_solid) .vertex_in(2, Type::MAT4, "inst_obmat") // .depth_layout(DepthLayout::GREATER) /* TODO */ .vertex_out(overlay_armature_sphere_solid_iface) - .vertex_source("armature_sphere_solid_vert.glsl") - .fragment_source("armature_sphere_solid_frag.glsl") + .vertex_source("overlay_armature_sphere_solid_vert.glsl") + .fragment_source("overlay_armature_sphere_solid_frag.glsl") .additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_armature_sphere_solid_clipped) @@ -79,9 +79,9 @@ GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline) .vertex_out(overlay_armature_shape_outline_iface) .geometry_layout(PrimitiveIn::LINES_ADJACENCY, PrimitiveOut::LINE_STRIP, 2) .geometry_out(overlay_armature_wire_iface) - .vertex_source("armature_shape_outline_vert.glsl") - .geometry_source("armature_shape_outline_geom.glsl") - .fragment_source("armature_wire_frag.glsl") + .vertex_source("overlay_armature_shape_outline_vert.glsl") + .geometry_source("overlay_armature_shape_outline_geom.glsl") + .fragment_source("overlay_armature_wire_frag.glsl") .additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline_clipped) @@ -100,8 +100,8 @@ GPU_SHADER_CREATE_INFO(overlay_armature_shape_solid) .vertex_in(2, Type::MAT4, "inst_obmat") .depth_write(DepthWrite::GREATER) .vertex_out(overlay_armature_shape_solid_iface) - .vertex_source("armature_shape_solid_vert.glsl") - .fragment_source("armature_shape_solid_frag.glsl") + .vertex_source("overlay_armature_shape_solid_vert.glsl") + .fragment_source("overlay_armature_shape_solid_frag.glsl") .additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_armature_shape_solid_clipped) @@ -115,8 +115,8 @@ GPU_SHADER_CREATE_INFO(overlay_armature_shape_wire) /* Per instance. */ .vertex_in(2, Type::MAT4, "inst_obmat") .vertex_out(overlay_armature_wire_iface) - .vertex_source("armature_shape_wire_vert.glsl") - .fragment_source("armature_wire_frag.glsl") + .vertex_source("overlay_armature_shape_wire_vert.glsl") + .fragment_source("overlay_armature_wire_frag.glsl") .additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_armature_shape_wire_clipped) @@ -140,8 +140,8 @@ GPU_SHADER_CREATE_INFO(overlay_armature_envelope_outline) .vertex_in(5, Type::VEC4, "outlineColorSize") .vertex_in(6, Type::VEC3, "xAxis") .vertex_out(overlay_armature_wire_iface) - .vertex_source("armature_envelope_outline_vert.glsl") - .fragment_source("armature_wire_frag.glsl") + .vertex_source("overlay_armature_envelope_outline_vert.glsl") + .fragment_source("overlay_armature_wire_frag.glsl") .additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_armature_envelope_outline_clipped) @@ -164,8 +164,8 @@ GPU_SHADER_CREATE_INFO(overlay_armature_envelope_solid) .vertex_in(5, Type::VEC3, "boneColor") .vertex_out(overlay_armature_envelope_solid_iface) .push_constant(Type::BOOL, "isDistance") - .vertex_source("armature_envelope_solid_vert.glsl") - .fragment_source("armature_envelope_solid_frag.glsl") + .vertex_source("overlay_armature_envelope_solid_vert.glsl") + .fragment_source("overlay_armature_envelope_solid_frag.glsl") .additional_info("overlay_frag_output", "overlay_armature_common"); GPU_SHADER_CREATE_INFO(overlay_armature_envelope_solid_clipped) @@ -198,8 +198,8 @@ GPU_SHADER_CREATE_INFO(overlay_armature_stick) .vertex_in(7, Type::VEC4, "tailColor") .define("do_wire", "(wireColor.a > 0.0)") .vertex_out(overlay_armature_stick_iface) - .vertex_source("armature_stick_vert.glsl") - .fragment_source("armature_stick_frag.glsl") + .vertex_source("overlay_armature_stick_vert.glsl") + .fragment_source("overlay_armature_stick_frag.glsl") .additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_armature_stick_clipped) @@ -218,12 +218,12 @@ GPU_SHADER_CREATE_INFO(overlay_armature_dof) .vertex_in(1, Type::VEC4, "color") .vertex_in(2, Type::MAT4, "inst_obmat") .vertex_out(overlay_armature_wire_iface) - .vertex_source("armature_dof_vert.glsl") + .vertex_source("overlay_armature_dof_vert.glsl") .additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_armature_dof_wire) .do_static_compilation(true) - .fragment_source("armature_dof_solid_frag.glsl") + .fragment_source("overlay_armature_dof_solid_frag.glsl") .additional_info("overlay_armature_dof"); GPU_SHADER_CREATE_INFO(overlay_armature_dof_wire_clipped) @@ -232,7 +232,7 @@ GPU_SHADER_CREATE_INFO(overlay_armature_dof_wire_clipped) GPU_SHADER_CREATE_INFO(overlay_armature_dof_solid) .do_static_compilation(true) - .fragment_source("armature_dof_solid_frag.glsl") + .fragment_source("overlay_armature_dof_solid_frag.glsl") .additional_info("overlay_armature_dof"); GPU_SHADER_CREATE_INFO(overlay_armature_dof_solid_clipped) @@ -251,8 +251,8 @@ GPU_SHADER_CREATE_INFO(overlay_armature_wire) .vertex_in(1, Type::VEC4, "color") .push_constant(Type::FLOAT, "alpha") .vertex_out(overlay_armature_wire_iface) - .vertex_source("armature_wire_vert.glsl") - .fragment_source("armature_wire_frag.glsl") + .vertex_source("overlay_armature_wire_vert.glsl") + .fragment_source("overlay_armature_wire_frag.glsl") .additional_info("overlay_frag_output", "draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_armature_wire_clipped) diff --git a/source/blender/draw/engines/overlay/shaders/infos/background_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh index c96d302d861..88a012c35c9 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/background_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh @@ -9,17 +9,15 @@ GPU_SHADER_CREATE_INFO(overlay_background) .sampler(1, ImageType::DEPTH_2D, "depthBuffer") .push_constant(Type::INT, "bgType") .push_constant(Type::VEC4, "colorOverride") - .fragment_source("background_frag.glsl") + .fragment_source("overlay_background_frag.glsl") .fragment_out(0, Type::VEC4, "fragColor") .additional_info("draw_fullscreen", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_clipbound) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .push_constant(Type::VEC4, "color") .push_constant(Type::VEC3, "boundbox", 8) - .vertex_source("clipbound_vert.glsl") + .vertex_source("overlay_clipbound_vert.glsl") .fragment_out(0, Type::VEC4, "fragColor") - .fragment_source("gpu_shader_uniform_color_frag.glsl") + .fragment_source("overlay_uniform_color_frag.glsl") .additional_info("draw_view"); diff --git a/source/blender/draw/engines/overlay/shaders/infos/edit_mode_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh index e6f15046838..58f96110887 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/edit_mode_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh @@ -19,7 +19,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common) .push_constant(Type::BOOL, "selectEdges") .push_constant(Type::FLOAT, "alpha") .push_constant(Type::IVEC4, "dataMask") - .vertex_source("edit_mesh_vert.glsl") + .vertex_source("overlay_edit_mesh_vert.glsl") .additional_info("draw_modelmat", "draw_globals"); GPU_SHADER_INTERFACE_INFO(overlay_edit_mesh_vert_iface, "") @@ -29,13 +29,12 @@ GPU_SHADER_INTERFACE_INFO(overlay_edit_mesh_vert_iface, "") GPU_SHADER_CREATE_INFO(overlay_edit_mesh_vert) .do_static_compilation(true) .builtins(BuiltinBits::POINT_SIZE) - .define("srgbTarget", "false") /* Colors are already in linear space. */ .define("VERT") .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::IVEC4, "data") .vertex_in(2, Type::VEC3, "vnor") .vertex_out(overlay_edit_mesh_vert_iface) - .fragment_source("gpu_shader_point_varying_color_frag.glsl") + .fragment_source("overlay_point_varying_color_frag.glsl") .additional_info("overlay_edit_mesh_common"); GPU_SHADER_INTERFACE_INFO(overlay_edit_mesh_edge_iface, "geometry_in") @@ -58,8 +57,8 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge) .vertex_out(overlay_edit_mesh_edge_iface) .geometry_out(overlay_edit_mesh_edge_geom_iface) .geometry_layout(PrimitiveIn::LINES, PrimitiveOut::TRIANGLE_STRIP, 4) - .geometry_source("edit_mesh_geom.glsl") - .fragment_source("edit_mesh_frag.glsl") + .geometry_source("overlay_edit_mesh_geom.glsl") + .fragment_source("overlay_edit_mesh_frag.glsl") .additional_info("overlay_edit_mesh_common"); GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat) @@ -69,13 +68,12 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat) GPU_SHADER_CREATE_INFO(overlay_edit_mesh_face) .do_static_compilation(true) - .define("srgbTarget", "false") /* Colors are already in linear space. */ .define("FACE") .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::IVEC4, "data") .vertex_in(2, Type::VEC3, "vnor") .vertex_out(overlay_edit_flat_color_iface) - .fragment_source("gpu_shader_3D_smooth_color_frag.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("overlay_edit_mesh_common"); GPU_SHADER_CREATE_INFO(overlay_edit_mesh_facedot) @@ -86,12 +84,11 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_facedot) .vertex_in(2, Type::VEC4, "norAndFlag") .define("vnor", "norAndFlag.xyz") .vertex_out(overlay_edit_flat_color_iface) - .fragment_source("gpu_shader_point_varying_color_frag.glsl") + .fragment_source("overlay_point_varying_color_frag.glsl") .additional_info("overlay_edit_mesh_common"); GPU_SHADER_CREATE_INFO(overlay_edit_mesh_normal) .do_static_compilation(true) - .define("srgbTarget", "false") /* Colors are already in linear space. */ .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::VEC4, "lnor") .vertex_in(2, Type::VEC4, "vnor") @@ -103,8 +100,8 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_normal) .push_constant(Type::BOOL, "isConstantScreenSizeNormals") .vertex_out(overlay_edit_flat_color_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_mesh_normal_vert.glsl") - .fragment_source("gpu_shader_flat_color_frag.glsl") + .vertex_source("overlay_edit_mesh_normal_vert.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_modelmat_instanced_attr", "draw_globals"); GPU_SHADER_INTERFACE_INFO(overlay_edit_mesh_analysis_iface, "").smooth(Type::VEC4, "weightColor"); @@ -116,20 +113,19 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_analysis) .sampler(0, ImageType::FLOAT_1D, "weightTex") .fragment_out(0, Type::VEC4, "fragColor") .vertex_out(overlay_edit_mesh_analysis_iface) - .vertex_source("edit_mesh_analysis_vert.glsl") - .fragment_source("edit_mesh_analysis_frag.glsl") + .vertex_source("overlay_edit_mesh_analysis_vert.glsl") + .fragment_source("overlay_edit_mesh_analysis_frag.glsl") .additional_info("draw_modelmat"); GPU_SHADER_CREATE_INFO(overlay_edit_mesh_skin_root) .do_static_compilation(true) - .define("srgbTarget", "false") /* Colors are already in linear space. */ .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::FLOAT, "size") .vertex_in(2, Type::VEC3, "local_pos") .vertex_out(overlay_edit_flat_color_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_mesh_skin_root_vert.glsl") - .fragment_source("gpu_shader_flat_color_frag.glsl") + .vertex_source("overlay_edit_mesh_skin_root_vert.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_modelmat_instanced_attr", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_mesh_vert_clipped) @@ -193,9 +189,9 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_edges) .push_constant(Type::FLOAT, "alpha") .push_constant(Type::FLOAT, "dashLength") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_uv_edges_vert.glsl") - .geometry_source("edit_uv_edges_geom.glsl") - .fragment_source("edit_uv_edges_frag.glsl") + .vertex_source("overlay_edit_uv_edges_vert.glsl") + .geometry_source("overlay_edit_uv_edges_geom.glsl") + .fragment_source("overlay_edit_uv_edges_frag.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_uv_edges_select) @@ -205,28 +201,24 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_edges_select) GPU_SHADER_CREATE_INFO(overlay_edit_uv_faces) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC2, "au") .vertex_in(1, Type::INT, "flag") .push_constant(Type::FLOAT, "uvOpacity") .vertex_out(overlay_edit_flat_color_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_uv_faces_vert.glsl") - .fragment_source("gpu_shader_flat_color_frag.glsl") + .vertex_source("overlay_edit_uv_faces_vert.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_uv_face_dots) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC2, "au") .vertex_in(1, Type::INT, "flag") .push_constant(Type::FLOAT, "pointSize") .vertex_out(overlay_edit_flat_color_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_uv_face_dots_vert.glsl") - .fragment_source("gpu_shader_flat_color_frag.glsl") + .vertex_source("overlay_edit_uv_face_dots_vert.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_INTERFACE_INFO(overlay_edit_uv_vert_iface, "") @@ -236,8 +228,6 @@ GPU_SHADER_INTERFACE_INFO(overlay_edit_uv_vert_iface, "") GPU_SHADER_CREATE_INFO(overlay_edit_uv_verts) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC2, "au") .vertex_in(1, Type::INT, "flag") .push_constant(Type::FLOAT, "pointSize") @@ -245,19 +235,17 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_verts) .push_constant(Type::VEC4, "color") .vertex_out(overlay_edit_uv_vert_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_uv_verts_vert.glsl") - .fragment_source("edit_uv_verts_frag.glsl") + .vertex_source("overlay_edit_uv_verts_vert.glsl") + .fragment_source("overlay_edit_uv_verts_frag.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_uv_tiled_image_borders) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .push_constant(Type::VEC4, "color") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_uv_tiled_image_borders_vert.glsl") - .fragment_source("gpu_shader_uniform_color_frag.glsl") + .vertex_source("overlay_edit_uv_tiled_image_borders_vert.glsl") + .fragment_source("overlay_uniform_color_frag.glsl") .additional_info("draw_mesh"); GPU_SHADER_INTERFACE_INFO(edit_uv_image_iface, "").smooth(Type::VEC2, "uvs"); @@ -266,13 +254,13 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_stencil_image) .do_static_compilation(true) .vertex_in(0, Type::VEC3, "pos") .vertex_out(edit_uv_image_iface) - .vertex_source("edit_uv_image_vert.glsl") + .vertex_source("overlay_edit_uv_image_vert.glsl") .sampler(0, ImageType::FLOAT_2D, "imgTexture") .push_constant(Type::BOOL, "imgPremultiplied") .push_constant(Type::BOOL, "imgAlphaBlend") .push_constant(Type::VEC4, "color") .fragment_out(0, Type::VEC4, "fragColor") - .fragment_source("image_frag.glsl") + .fragment_source("overlay_image_frag.glsl") .additional_info("draw_mesh"); GPU_SHADER_CREATE_INFO(overlay_edit_uv_mask_image) @@ -282,8 +270,8 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_mask_image) .sampler(0, ImageType::FLOAT_2D, "imgTexture") .push_constant(Type::VEC4, "color") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_uv_image_vert.glsl") - .fragment_source("edit_uv_image_mask_frag.glsl") + .vertex_source("overlay_edit_uv_image_vert.glsl") + .fragment_source("overlay_edit_uv_image_mask_frag.glsl") .additional_info("draw_mesh"); /** \} */ @@ -293,14 +281,12 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_mask_image) * \{ */ GPU_SHADER_CREATE_INFO(overlay_edit_uv_stretching) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC2, "pos") .push_constant(Type::VEC2, "aspect") .vertex_out(overlay_edit_nopersp_color_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_uv_stretching_vert.glsl") - .fragment_source("gpu_shader_2D_smooth_color_frag.glsl") + .vertex_source("overlay_edit_uv_stretching_vert.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_uv_stretching_area) @@ -328,8 +314,6 @@ GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type::IN GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle) .do_static_compilation(true) .typedef_source("overlay_shader_shared.h") - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::INT, "data") .vertex_out(overlay_edit_curve_handle_iface) @@ -338,9 +322,9 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle) .push_constant(Type::BOOL, "showCurveHandles") .push_constant(Type::INT, "curveHandleDisplay") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_curve_handle_vert.glsl") - .geometry_source("edit_curve_handle_geom.glsl") - .fragment_source("gpu_shader_3D_smooth_color_frag.glsl") + .vertex_source("overlay_edit_curve_handle_vert.glsl") + .geometry_source("overlay_edit_curve_handle_geom.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_clipped) @@ -350,16 +334,14 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_clipped) GPU_SHADER_CREATE_INFO(overlay_edit_curve_point) .do_static_compilation(true) .typedef_source("overlay_shader_shared.h") - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::INT, "data") .vertex_out(overlay_edit_flat_color_iface) .push_constant(Type::BOOL, "showCurveHandles") .push_constant(Type::INT, "curveHandleDisplay") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_curve_point_vert.glsl") - .fragment_source("gpu_shader_point_varying_color_frag.glsl") + .vertex_source("overlay_edit_curve_point_vert.glsl") + .fragment_source("overlay_point_varying_color_frag.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_curve_point_clipped) @@ -368,8 +350,6 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_point_clipped) GPU_SHADER_CREATE_INFO(overlay_edit_curve_wire) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::VEC3, "nor") .vertex_in(2, Type::VEC3, "tan") @@ -377,8 +357,8 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_wire) .push_constant(Type::FLOAT, "normalSize") .vertex_out(overlay_edit_flat_color_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_curve_wire_vert.glsl") - .fragment_source("gpu_shader_flat_color_frag.glsl") + .vertex_source("overlay_edit_curve_wire_vert.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_modelmat", "draw_resource_id_uniform", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_curve_wire_clipped) @@ -393,14 +373,12 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_wire_clipped) GPU_SHADER_CREATE_INFO(overlay_edit_lattice_point) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::INT, "data") .vertex_out(overlay_edit_flat_color_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_lattice_point_vert.glsl") - .fragment_source("gpu_shader_point_varying_color_frag.glsl") + .vertex_source("overlay_edit_lattice_point_vert.glsl") + .fragment_source("overlay_point_varying_color_frag.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_lattice_point_clipped) @@ -409,15 +387,13 @@ GPU_SHADER_CREATE_INFO(overlay_edit_lattice_point_clipped) GPU_SHADER_CREATE_INFO(overlay_edit_lattice_wire) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::FLOAT, "weight") .sampler(0, ImageType::FLOAT_1D, "weightTex") .vertex_out(overlay_edit_smooth_color_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_lattice_wire_vert.glsl") - .fragment_source("gpu_shader_3D_smooth_color_frag.glsl") + .vertex_source("overlay_edit_lattice_wire_vert.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_lattice_wire_clipped) @@ -432,16 +408,14 @@ GPU_SHADER_CREATE_INFO(overlay_edit_lattice_wire_clipped) GPU_SHADER_CREATE_INFO(overlay_edit_particle_strand) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::FLOAT, "color") .sampler(0, ImageType::FLOAT_1D, "weightTex") .push_constant(Type::BOOL, "useWeight") .vertex_out(overlay_edit_smooth_color_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_particle_strand_vert.glsl") - .fragment_source("gpu_shader_3D_smooth_color_frag.glsl") + .vertex_source("overlay_edit_particle_strand_vert.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_particle_strand_clipped) @@ -450,14 +424,12 @@ GPU_SHADER_CREATE_INFO(overlay_edit_particle_strand_clipped) GPU_SHADER_CREATE_INFO(overlay_edit_particle_point) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::FLOAT, "color") .vertex_out(overlay_edit_flat_color_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_particle_point_vert.glsl") - .fragment_source("gpu_shader_point_varying_color_frag.glsl") + .vertex_source("overlay_edit_particle_point_vert.glsl") + .fragment_source("overlay_point_varying_color_frag.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_particle_point_clipped) @@ -472,8 +444,6 @@ GPU_SHADER_CREATE_INFO(overlay_edit_particle_point_clipped) GPU_SHADER_CREATE_INFO(overlay_edit_gpencil) .typedef_source("overlay_shader_shared.h") - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::INT, "ma") .vertex_in(2, Type::UINT, "vflag") @@ -487,13 +457,13 @@ GPU_SHADER_CREATE_INFO(overlay_edit_gpencil) .push_constant(Type::VEC4, "gpEditColor") .sampler(0, ImageType::FLOAT_1D, "weightTex") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_gpencil_vert.glsl") + .vertex_source("overlay_edit_gpencil_vert.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_gpencil_wire) .do_static_compilation(true) .vertex_out(overlay_edit_smooth_color_iface) - .fragment_source("gpu_shader_3D_smooth_color_frag.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("overlay_edit_gpencil"); GPU_SHADER_CREATE_INFO(overlay_edit_gpencil_wire_clipped) @@ -504,7 +474,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_gpencil_point) .do_static_compilation(true) .define("USE_POINTS") .vertex_out(overlay_edit_flat_color_iface) - .fragment_source("gpu_shader_point_varying_color_frag.glsl") + .fragment_source("overlay_point_varying_color_frag.glsl") .additional_info("overlay_edit_gpencil"); GPU_SHADER_CREATE_INFO(overlay_edit_gpencil_point_clipped) @@ -514,8 +484,6 @@ GPU_SHADER_CREATE_INFO(overlay_edit_gpencil_point_clipped) /* TODO(fclem): Refactor this to take list of point instead of drawing 1 point per drawcall. */ GPU_SHADER_CREATE_INFO(overlay_edit_gpencil_guide_point) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::INT, "data") .vertex_out(overlay_edit_flat_color_iface) @@ -523,8 +491,8 @@ GPU_SHADER_CREATE_INFO(overlay_edit_gpencil_guide_point) .push_constant(Type::FLOAT, "pSize") .push_constant(Type::VEC4, "pColor") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_gpencil_guide_vert.glsl") - .fragment_source("gpu_shader_point_varying_color_frag.glsl") + .vertex_source("overlay_edit_gpencil_guide_vert.glsl") + .fragment_source("overlay_point_varying_color_frag.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_edit_gpencil_guide_point_clipped) @@ -542,8 +510,8 @@ GPU_SHADER_CREATE_INFO(overlay_edit_gpencil_guide_point_clipped) GPU_SHADER_CREATE_INFO(overlay_depth_only) .do_static_compilation(true) .vertex_in(0, Type::VEC3, "pos") - .vertex_source("depth_only_vert.glsl") - .fragment_source("gpu_shader_depth_only_frag.glsl") + .vertex_source("overlay_depth_only_vert.glsl") + .fragment_source("overlay_depth_only_frag.glsl") .additional_info("draw_mesh"); GPU_SHADER_CREATE_INFO(overlay_depth_only_clipped) @@ -558,13 +526,11 @@ GPU_SHADER_CREATE_INFO(overlay_depth_only_clipped) GPU_SHADER_CREATE_INFO(overlay_uniform_color) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .push_constant(Type::VEC4, "color") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("depth_only_vert.glsl") - .fragment_source("gpu_shader_uniform_color_frag.glsl") + .vertex_source("overlay_depth_only_vert.glsl") + .fragment_source("overlay_uniform_color_frag.glsl") .additional_info("draw_mesh"); GPU_SHADER_CREATE_INFO(overlay_uniform_color_clipped) diff --git a/source/blender/draw/engines/overlay/shaders/infos/extra_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh index b9b1b73dbd4..5b50bbcaa55 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/extra_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh @@ -21,8 +21,8 @@ GPU_SHADER_CREATE_INFO(overlay_extra) .vertex_out(overlay_extra_iface) .fragment_out(0, Type::VEC4, "fragColor") .fragment_out(1, Type::VEC4, "lineOutput") - .vertex_source("extra_vert.glsl") - .fragment_source("extra_frag.glsl") + .vertex_source("overlay_extra_vert.glsl") + .fragment_source("overlay_extra_frag.glsl") .additional_info("draw_view", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_extra_select) @@ -53,8 +53,8 @@ GPU_SHADER_CREATE_INFO(overlay_extra_grid) .push_constant(Type::BOOL, "isTransform") .vertex_out(overlay_extra_grid_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("extra_lightprobe_grid_vert.glsl") - .fragment_source("gpu_shader_point_varying_color_frag.glsl") + .vertex_source("overlay_extra_lightprobe_grid_vert.glsl") + .fragment_source("overlay_point_varying_color_frag.glsl") .additional_info("draw_view", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_extra_grid_clipped) @@ -75,8 +75,8 @@ GPU_SHADER_CREATE_INFO(overlay_extra_groundline) .vertex_out(overlay_extra_iface) .fragment_out(0, Type::VEC4, "fragColor") .fragment_out(1, Type::VEC4, "lineOutput") - .vertex_source("extra_groundline_vert.glsl") - .fragment_source("extra_frag.glsl") + .vertex_source("overlay_extra_groundline_vert.glsl") + .fragment_source("overlay_extra_frag.glsl") .additional_info("draw_view", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_extra_groundline_clipped) @@ -103,8 +103,8 @@ GPU_SHADER_CREATE_INFO(overlay_extra_wire) .vertex_out(overlay_extra_wire_iface) .fragment_out(0, Type::VEC4, "fragColor") .fragment_out(1, Type::VEC4, "lineOutput") - .vertex_source("extra_wire_vert.glsl") - .fragment_source("extra_wire_frag.glsl") + .vertex_source("overlay_extra_wire_vert.glsl") + .fragment_source("overlay_extra_wire_frag.glsl") .additional_info("draw_modelmat", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_extra_wire_select) @@ -148,8 +148,8 @@ GPU_SHADER_CREATE_INFO(overlay_extra_point) .push_constant(Type::VEC4, "color") .vertex_out(overlay_extra_point_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("extra_point_vert.glsl") - .fragment_source("gpu_shader_point_varying_color_varying_outline_aa_frag.glsl") + .vertex_source("overlay_extra_point_vert.glsl") + .fragment_source("overlay_point_varying_color_varying_outline_aa_frag.glsl") .additional_info("draw_modelmat", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_extra_point_clipped) @@ -165,8 +165,8 @@ GPU_SHADER_CREATE_INFO(overlay_extra_loose_point) .vertex_out(overlay_extra_loose_point_iface) .fragment_out(0, Type::VEC4, "fragColor") .fragment_out(1, Type::VEC4, "lineOutput") - .vertex_source("extra_loose_point_vert.glsl") - .fragment_source("extra_loose_point_frag.glsl") + .vertex_source("overlay_extra_loose_point_vert.glsl") + .fragment_source("overlay_extra_loose_point_frag.glsl") .additional_info("draw_modelmat", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_extra_loose_point_clipped) @@ -194,9 +194,9 @@ GPU_SHADER_CREATE_INFO(overlay_motion_path_line) .geometry_out(overlay_motion_path_line_iface) .geometry_layout(PrimitiveIn::LINES, PrimitiveOut::TRIANGLE_STRIP, 4) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("motion_path_line_vert.glsl") - .geometry_source("motion_path_line_geom.glsl") - .fragment_source("motion_path_line_frag.glsl") + .vertex_source("overlay_motion_path_line_vert.glsl") + .geometry_source("overlay_motion_path_line_geom.glsl") + .fragment_source("overlay_motion_path_line_frag.glsl") .additional_info("draw_view", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_motion_path_line_clipped) @@ -215,8 +215,8 @@ GPU_SHADER_CREATE_INFO(overlay_motion_path_point) .push_constant(Type::VEC3, "customColor") .vertex_out(overlay_motion_path_point_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("motion_path_point_vert.glsl") - .fragment_source("gpu_shader_point_varying_color_frag.glsl") + .vertex_source("overlay_motion_path_point_vert.glsl") + .fragment_source("overlay_point_varying_color_frag.glsl") .additional_info("draw_view", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_motion_path_point_clipped) @@ -242,8 +242,8 @@ GPU_SHADER_CREATE_INFO(overlay_image) .vertex_out(overlay_image_iface) .sampler(0, ImageType::FLOAT_2D, "imgTexture") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("image_vert.glsl") - .fragment_source("image_frag.glsl") + .vertex_source("overlay_image_vert.glsl") + .fragment_source("overlay_image_frag.glsl") .additional_info("draw_mesh"); GPU_SHADER_CREATE_INFO(overlay_image_clipped) @@ -266,8 +266,8 @@ GPU_SHADER_CREATE_INFO(overlay_gpencil_canvas) .push_constant(Type::INT, "halfLineCount") .fragment_out(0, Type::VEC4, "fragColor") .fragment_out(1, Type::VEC4, "lineOutput") - .vertex_source("edit_gpencil_canvas_vert.glsl") - .fragment_source("extra_frag.glsl") + .vertex_source("overlay_edit_gpencil_canvas_vert.glsl") + .fragment_source("overlay_extra_frag.glsl") .additional_info("draw_mesh", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_gpencil_canvas_clipped) @@ -289,7 +289,7 @@ GPU_SHADER_CREATE_INFO(overlay_particle) .vertex_in(1, Type::VEC4, "part_rot") .vertex_in(2, Type::FLOAT, "part_val") .vertex_out(overlay_particle_iface) - .vertex_source("particle_vert.glsl") + .vertex_source("overlay_particle_vert.glsl") .additional_info("draw_globals"); GPU_SHADER_CREATE_INFO(overlay_particle_dot) @@ -299,7 +299,7 @@ GPU_SHADER_CREATE_INFO(overlay_particle_dot) .define("pos", "vec3(0.0)") .fragment_out(0, Type::VEC4, "fragColor") .fragment_out(1, Type::VEC4, "lineOutput") - .fragment_source("particle_frag.glsl") + .fragment_source("overlay_particle_frag.glsl") .additional_info("overlay_particle", "draw_mesh"); GPU_SHADER_CREATE_INFO(overlay_particle_dot_clipped) @@ -308,13 +308,11 @@ GPU_SHADER_CREATE_INFO(overlay_particle_dot_clipped) GPU_SHADER_CREATE_INFO(overlay_particle_shape) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") /* Instantiated Attrs. */ .vertex_in(3, Type::VEC3, "pos") .vertex_in(4, Type::INT, "vclass") .fragment_out(0, Type::VEC4, "fragColor") - .fragment_source("gpu_shader_flat_color_frag.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("overlay_particle", "draw_modelmat", "draw_resource_id_uniform"); GPU_SHADER_CREATE_INFO(overlay_particle_shape_clipped) diff --git a/source/blender/draw/engines/overlay/shaders/infos/facing_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_facing_info.hh index 6d6806eaa80..6d528bbba62 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/facing_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_facing_info.hh @@ -5,8 +5,8 @@ GPU_SHADER_CREATE_INFO(overlay_facing) .do_static_compilation(true) .vertex_in(0, Type::VEC3, "pos") - .vertex_source("facing_vert.glsl") - .fragment_source("facing_frag.glsl") + .vertex_source("overlay_facing_vert.glsl") + .fragment_source("overlay_facing_frag.glsl") .fragment_out(0, Type::VEC4, "fragColor") .additional_info("draw_mesh", "draw_globals"); diff --git a/source/blender/draw/engines/overlay/shaders/infos/grid_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh index d02014c98a0..a8f1281d53a 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/grid_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh @@ -15,8 +15,8 @@ GPU_SHADER_CREATE_INFO(overlay_grid) .uniform_buf(3, "OVERLAY_GridData", "grid_buf") .push_constant(Type::VEC3, "plane_axes") .push_constant(Type::INT, "grid_flag") - .vertex_source("grid_vert.glsl") - .fragment_source("grid_frag.glsl") + .vertex_source("overlay_grid_vert.glsl") + .fragment_source("overlay_grid_frag.glsl") .additional_info("draw_view", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_grid_background) @@ -25,17 +25,15 @@ GPU_SHADER_CREATE_INFO(overlay_grid_background) .sampler(0, ImageType::DEPTH_2D, "depthBuffer") .push_constant(Type::VEC4, "color") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_uv_tiled_image_borders_vert.glsl") - .fragment_source("grid_background_frag.glsl") + .vertex_source("overlay_edit_uv_tiled_image_borders_vert.glsl") + .fragment_source("overlay_grid_background_frag.glsl") .additional_info("draw_modelmat"); GPU_SHADER_CREATE_INFO(overlay_grid_image) .do_static_compilation(true) - /* NOTE: Color already in Linear space. Which is what we want. */ - .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") .push_constant(Type::VEC4, "color") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("edit_uv_tiled_image_borders_vert.glsl") - .fragment_source("gpu_shader_uniform_color_frag.glsl") + .vertex_source("overlay_edit_uv_tiled_image_borders_vert.glsl") + .fragment_source("overlay_uniform_color_frag.glsl") .additional_info("draw_modelmat"); diff --git a/source/blender/draw/engines/overlay/shaders/infos/outline_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_outline_info.hh index 21575747efa..6f6a9c1622d 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/outline_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_outline_info.hh @@ -13,13 +13,13 @@ GPU_SHADER_CREATE_INFO(overlay_outline_prepass) .vertex_out(overlay_outline_prepass_iface) /* Using uint because 16bit uint can contain more ids than int. */ .fragment_out(0, Type::UINT, "out_object_id") - .fragment_source("outline_prepass_frag.glsl") + .fragment_source("overlay_outline_prepass_frag.glsl") .additional_info("draw_resource_handle"); GPU_SHADER_CREATE_INFO(overlay_outline_prepass_mesh) .do_static_compilation(true) .vertex_in(0, Type::VEC3, "pos") - .vertex_source("outline_prepass_vert.glsl") + .vertex_source("overlay_outline_prepass_vert.glsl") .additional_info("draw_mesh", "overlay_outline_prepass") .additional_info("draw_object_infos"); @@ -36,8 +36,8 @@ GPU_SHADER_CREATE_INFO(overlay_outline_prepass_wire) .vertex_out(overlay_outline_prepass_wire_iface) .geometry_layout(PrimitiveIn::LINES_ADJACENCY, PrimitiveOut::LINE_STRIP, 2) .geometry_out(overlay_outline_prepass_iface) - .vertex_source("outline_prepass_vert.glsl") - .geometry_source("outline_prepass_geom.glsl") + .vertex_source("overlay_outline_prepass_vert.glsl") + .geometry_source("overlay_outline_prepass_geom.glsl") .additional_info("draw_mesh", "overlay_outline_prepass") .additional_info("draw_object_infos"); @@ -56,12 +56,12 @@ GPU_SHADER_CREATE_INFO(overlay_outline_prepass_gpencil) .push_constant(Type::BOOL, "isTransform") .vertex_out(overlay_outline_prepass_iface) .vertex_out(overlay_outline_prepass_gpencil_iface) - .vertex_source("outline_prepass_gpencil_vert.glsl") + .vertex_source("overlay_outline_prepass_gpencil_vert.glsl") .push_constant(Type::BOOL, "gpStrokeOrder3d") /* TODO(fclem): Move to a GPencil object UBO. */ .push_constant(Type::VEC4, "gpDepthPlane") /* TODO(fclem): Move to a GPencil object UBO. */ /* Using uint because 16bit uint can contain more ids than int. */ .fragment_out(0, Type::UINT, "out_object_id") - .fragment_source("outline_prepass_gpencil_frag.glsl") + .fragment_source("overlay_outline_prepass_gpencil_frag.glsl") .additional_info("draw_gpencil", "draw_resource_handle"); GPU_SHADER_CREATE_INFO(overlay_outline_prepass_gpencil_clipped) @@ -70,7 +70,7 @@ GPU_SHADER_CREATE_INFO(overlay_outline_prepass_gpencil_clipped) GPU_SHADER_CREATE_INFO(overlay_outline_prepass_pointcloud) .do_static_compilation(true) - .vertex_source("outline_prepass_pointcloud_vert.glsl") + .vertex_source("overlay_outline_prepass_pointcloud_vert.glsl") .additional_info("draw_pointcloud", "overlay_outline_prepass") .additional_info("draw_object_infos"); @@ -95,7 +95,7 @@ GPU_SHADER_CREATE_INFO(overlay_outline_detect) .sampler(2, ImageType::DEPTH_2D, "sceneDepth") .fragment_out(0, Type::VEC4, "fragColor") .fragment_out(1, Type::VEC4, "lineOutput") - .fragment_source("outline_detect_frag.glsl") + .fragment_source("overlay_outline_detect_frag.glsl") .additional_info("draw_fullscreen", "draw_view", "draw_globals"); /** \} */ diff --git a/source/blender/draw/engines/overlay/shaders/infos/paint_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh index bbec79d515f..3083d5a463b 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/paint_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh @@ -10,13 +10,12 @@ GPU_SHADER_CREATE_INFO(overlay_paint_face) .do_static_compilation(true) - .define("srgbTarget", "false") /* NOTE: Color already in Linear space. */ .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::VEC4, "nor") /* Select flag on the 4th component. */ .push_constant(Type::VEC4, "color") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("paint_face_vert.glsl") - .fragment_source("gpu_shader_uniform_color_frag.glsl") + .vertex_source("overlay_paint_face_vert.glsl") + .fragment_source("overlay_uniform_color_frag.glsl") .additional_info("draw_modelmat"); GPU_SHADER_CREATE_INFO(overlay_paint_face_clipped) @@ -40,8 +39,8 @@ GPU_SHADER_CREATE_INFO(overlay_paint_point) .vertex_in(1, Type::VEC4, "nor") /* Select flag on the 4th component. */ .vertex_out(overlay_overlay_paint_point_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("paint_point_vert.glsl") - .fragment_source("gpu_shader_point_varying_color_frag.glsl") + .vertex_source("overlay_paint_point_vert.glsl") + .fragment_source("overlay_point_varying_color_frag.glsl") .additional_info("draw_modelmat", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_paint_point_clipped) @@ -70,8 +69,8 @@ GPU_SHADER_CREATE_INFO(overlay_paint_texture) .push_constant(Type::BOOL, "maskInvertStencil") .push_constant(Type::BOOL, "maskImagePremultiplied") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("paint_texture_vert.glsl") - .fragment_source("paint_texture_frag.glsl") + .vertex_source("overlay_paint_texture_vert.glsl") + .fragment_source("overlay_paint_texture_frag.glsl") .additional_info("draw_modelmat"); GPU_SHADER_CREATE_INFO(overlay_paint_texture_clipped) @@ -97,8 +96,8 @@ GPU_SHADER_CREATE_INFO(overlay_paint_vertcol) .push_constant(Type::FLOAT, "opacity") /* `1.0` by default. */ .push_constant(Type::BOOL, "useAlphaBlend") /* `false` by default. */ .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("paint_vertcol_vert.glsl") - .fragment_source("paint_vertcol_frag.glsl") + .vertex_source("overlay_paint_vertcol_vert.glsl") + .fragment_source("overlay_paint_vertcol_frag.glsl") .additional_info("draw_modelmat"); GPU_SHADER_CREATE_INFO(overlay_paint_vertcol_clipped) @@ -129,8 +128,8 @@ GPU_SHADER_CREATE_INFO(overlay_paint_weight) .push_constant(Type::FLOAT, "opacity") /* `1.0` by default. */ .push_constant(Type::BOOL, "drawContours") /* `false` by default. */ .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("paint_weight_vert.glsl") - .fragment_source("paint_weight_frag.glsl") + .vertex_source("overlay_paint_weight_vert.glsl") + .fragment_source("overlay_paint_weight_frag.glsl") .additional_info("draw_modelmat", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_paint_weight_fake_shading) @@ -162,14 +161,13 @@ GPU_SHADER_INTERFACE_INFO(overlay_paint_wire_iface, "").flat(Type::VEC4, "finalC GPU_SHADER_CREATE_INFO(overlay_paint_wire) .do_static_compilation(true) - .define("srgbTarget", "false") /* NOTE: Color already in Linear space. */ .vertex_in(0, Type::VEC3, "pos") .vertex_in(1, Type::VEC4, "nor") /* flag stored in w */ .vertex_out(overlay_paint_wire_iface) .push_constant(Type::BOOL, "useSelect") .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("paint_wire_vert.glsl") - .fragment_source("gpu_shader_flat_color_frag.glsl") + .vertex_source("overlay_paint_wire_vert.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_modelmat", "draw_globals"); GPU_SHADER_CREATE_INFO(overlay_paint_wire_clipped) diff --git a/source/blender/draw/engines/overlay/shaders/infos/sculpt_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_sculpt_info.hh index d4f1ca44362..3a53bd388a6 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/sculpt_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_sculpt_info.hh @@ -15,8 +15,8 @@ GPU_SHADER_CREATE_INFO(overlay_sculpt_mask) .vertex_in(1, Type::VEC3, "fset") .vertex_in(2, Type::FLOAT, "msk") .vertex_out(overlay_sculpt_mask_iface) - .vertex_source("sculpt_mask_vert.glsl") - .fragment_source("sculpt_mask_frag.glsl") + .vertex_source("overlay_sculpt_mask_vert.glsl") + .fragment_source("overlay_sculpt_mask_frag.glsl") .fragment_out(0, Type::VEC4, "fragColor") .additional_info("draw_mesh", "draw_object_infos", "draw_globals"); diff --git a/source/blender/draw/engines/overlay/shaders/infos/volume_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_volume_info.hh index 5853e974eeb..3740b42ba26 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/volume_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_volume_info.hh @@ -10,8 +10,6 @@ GPU_SHADER_INTERFACE_INFO(overlay_volume_velocity_iface, "").smooth(Type::VEC4, GPU_SHADER_CREATE_INFO(overlay_volume_velocity) .do_static_compilation(true) - /* Colors are already in linear space. */ - .define("srgbTarget", "false") .sampler(0, ImageType::FLOAT_3D, "velocityX") .sampler(1, ImageType::FLOAT_3D, "velocityY") .sampler(2, ImageType::FLOAT_3D, "velocityZ") @@ -28,8 +26,8 @@ GPU_SHADER_CREATE_INFO(overlay_volume_velocity) .push_constant(Type::IVEC3, "adaptiveCellOffset") .vertex_out(overlay_volume_velocity_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("volume_velocity_vert.glsl") - .fragment_source("gpu_shader_3D_smooth_color_frag.glsl") + .vertex_source("overlay_volume_velocity_vert.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_volume"); GPU_SHADER_CREATE_INFO(overlay_volume_velocity_mac) @@ -55,8 +53,6 @@ GPU_SHADER_INTERFACE_INFO(overlay_volume_gridlines_iface, "").flat(Type::VEC4, " GPU_SHADER_CREATE_INFO(overlay_volume_gridlines) .do_static_compilation(true) - /* Colors are already in linear space. */ - .define("srgbTarget", "false") .push_constant(Type::FLOAT, "slicePosition") .push_constant(Type::INT, "sliceAxis") /* FluidDomainSettings.res */ @@ -69,8 +65,8 @@ GPU_SHADER_CREATE_INFO(overlay_volume_gridlines) .push_constant(Type::IVEC3, "adaptiveCellOffset") .vertex_out(overlay_volume_gridlines_iface) .fragment_out(0, Type::VEC4, "fragColor") - .vertex_source("volume_gridlines_vert.glsl") - .fragment_source("gpu_shader_flat_color_frag.glsl") + .vertex_source("overlay_volume_gridlines_vert.glsl") + .fragment_source("overlay_varying_color.glsl") .additional_info("draw_volume"); GPU_SHADER_CREATE_INFO(overlay_volume_gridlines_flags) diff --git a/source/blender/draw/engines/overlay/shaders/infos/wireframe_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_wireframe_info.hh index 16b59f6bb7d..1899b191741 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/wireframe_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_wireframe_info.hh @@ -23,8 +23,8 @@ GPU_SHADER_CREATE_INFO(overlay_wireframe) .vertex_in(1, Type::VEC3, "nor") .vertex_in(2, Type::FLOAT, "wd") /* wire-data. */ .vertex_out(overlay_wireframe_iface) - .vertex_source("wireframe_vert.glsl") - .fragment_source("wireframe_frag.glsl") + .vertex_source("overlay_wireframe_vert.glsl") + .fragment_source("overlay_wireframe_frag.glsl") .fragment_out(0, Type::VEC4, "fragColor") .fragment_out(1, Type::VEC4, "lineOutput") .additional_info("draw_mesh", "draw_object_infos", "draw_globals"); diff --git a/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_antialiasing_frag.glsl index f28a809fdab..f28a809fdab 100644 --- a/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_antialiasing_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_dof_solid_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl index d46abbf79ee..d46abbf79ee 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_dof_solid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_dof_solid_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_dof_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_dof_vert.glsl index b3c9ce5dfd2..b3c9ce5dfd2 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_dof_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_dof_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_envelope_outline_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl index 0a8e279e9b0..0a8e279e9b0 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_envelope_outline_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_envelope_solid_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_frag.glsl index a90d2e3e406..a90d2e3e406 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_envelope_solid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_envelope_solid_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_vert.glsl index 2dd86a57dfd..2dd86a57dfd 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_envelope_solid_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_solid_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_shape_outline_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_geom.glsl index 47c5dada708..47c5dada708 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_shape_outline_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_geom.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_shape_outline_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert.glsl index 29319b3f7ac..29319b3f7ac 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_shape_outline_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_shape_solid_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl index 8e1768846dc..8e1768846dc 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_shape_solid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_shape_solid_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_vert.glsl index cdbe8c3d7df..cdbe8c3d7df 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_shape_solid_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_solid_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_shape_wire_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_wire_vert.glsl index cee86956c43..cee86956c43 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_shape_wire_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_wire_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_sphere_outline_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_outline_vert.glsl index 31369e0c3df..31369e0c3df 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_sphere_outline_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_outline_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_frag.glsl index e60b6e94492..e60b6e94492 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_vert.glsl index abbaad8cd10..abbaad8cd10 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_sphere_solid_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_stick_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_stick_frag.glsl index 2e42cdf0517..2e42cdf0517 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_stick_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_stick_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_stick_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_stick_vert.glsl index b5edcd2858b..b5edcd2858b 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_stick_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_stick_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_wire_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_wire_frag.glsl index 2c454a8becd..2c454a8becd 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_wire_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_wire_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/armature_wire_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_wire_vert.glsl index c89d0249e4f..c89d0249e4f 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_wire_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_wire_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/background_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_background_frag.glsl index b25dcae9fca..b25dcae9fca 100644 --- a/source/blender/draw/engines/overlay/shaders/background_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_background_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/clipbound_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_clipbound_vert.glsl index c065a66414f..c065a66414f 100644 --- a/source/blender/draw/engines/overlay/shaders/clipbound_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_clipbound_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/common_overlay_lib.glsl b/source/blender/draw/engines/overlay/shaders/overlay_common_lib.glsl index 65aeb81a4ef..65aeb81a4ef 100644 --- a/source/blender/draw/engines/overlay/shaders/common_overlay_lib.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_common_lib.glsl diff --git a/source/blender/draw/engines/overlay/shaders/overlay_depth_only_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_depth_only_frag.glsl new file mode 100644 index 00000000000..59efdd8d538 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_depth_only_frag.glsl @@ -0,0 +1,6 @@ + +void main() +{ + /* No color output, only depth (line below is implicit). */ + // gl_FragDepth = gl_FragCoord.z; +} diff --git a/source/blender/draw/engines/overlay/shaders/depth_only_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_depth_only_vert.glsl index d403890f44e..d403890f44e 100644 --- a/source/blender/draw/engines/overlay/shaders/depth_only_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_depth_only_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_geom.glsl index 7d92baea595..7d92baea595 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_geom.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert.glsl index 186cc010f45..186cc010f45 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_curve_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_point_vert.glsl index a30496177c3..a30496177c3 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_curve_point_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_point_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_curve_wire_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_wire_vert.glsl index 183df7e5450..183df7e5450 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_curve_wire_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_wire_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_gpencil_canvas_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_gpencil_canvas_vert.glsl index 47d9439ed80..47d9439ed80 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_gpencil_canvas_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_gpencil_canvas_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_gpencil_guide_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_gpencil_guide_vert.glsl index a5091345539..a5091345539 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_gpencil_guide_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_gpencil_guide_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_gpencil_vert.glsl index f5d6e89d016..f5d6e89d016 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_gpencil_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_lattice_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_lattice_point_vert.glsl index 38ba80a981a..38ba80a981a 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_lattice_point_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_lattice_point_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_lattice_wire_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_lattice_wire_vert.glsl index 440dfdc1482..440dfdc1482 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_lattice_wire_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_lattice_wire_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_analysis_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_analysis_frag.glsl index 430ace8726a..430ace8726a 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_mesh_analysis_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_analysis_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_analysis_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_analysis_vert.glsl index 1e163dc9a9a..1e163dc9a9a 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_mesh_analysis_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_analysis_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_common_lib.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_common_lib.glsl index 72b0a43cdb4..72b0a43cdb4 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_mesh_common_lib.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_common_lib.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_frag.glsl index 2fd155f715c..2fd155f715c 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_mesh_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_geom.glsl index 82f957b2071..82f957b2071 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_mesh_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_geom.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_normal_vert.glsl index 6ff8d0665d1..6ff8d0665d1 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_normal_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_skin_root_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_skin_root_vert.glsl index f1fbdac7847..f1fbdac7847 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_mesh_skin_root_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_skin_root_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert.glsl index 166ac1a37b0..374fb50af75 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert.glsl @@ -1,7 +1,7 @@ #pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl) #pragma BLENDER_REQUIRE(common_view_lib.glsl) -#pragma BLENDER_REQUIRE(edit_mesh_common_lib.glsl) +#pragma BLENDER_REQUIRE(overlay_edit_mesh_common_lib.glsl) #ifdef EDGE /* Ugly but needed to keep the same vertex shader code for other passes. */ diff --git a/source/blender/draw/engines/overlay/shaders/edit_particle_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_particle_point_vert.glsl index 956b27e948d..956b27e948d 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_particle_point_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_particle_point_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_particle_strand_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_particle_strand_vert.glsl index 6a92206d524..6a92206d524 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_particle_strand_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_particle_strand_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl index 9c0ce4ecc8a..a849cb5160a 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_frag.glsl @@ -1,4 +1,4 @@ -#pragma BLENDER_REQUIRE(common_overlay_lib.glsl) +#pragma BLENDER_REQUIRE(overlay_common_lib.glsl) /** * We want to know how much a pixel is covered by a line. diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_geom.glsl index ac8d33cd727..8b19f671139 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_geom.glsl @@ -1,4 +1,4 @@ -#pragma BLENDER_REQUIRE(common_overlay_lib.glsl) +#pragma BLENDER_REQUIRE(overlay_common_lib.glsl) void do_vertex( vec4 pos, float selection_fac, vec2 stipple_start, vec2 stipple_pos, float coord, vec2 offset) diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl index 23f1a44c321..23f1a44c321 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_face_dots_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_face_dots_vert.glsl index 280b31ea463..280b31ea463 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_face_dots_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_face_dots_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_faces_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl index 80ea6228675..80ea6228675 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_faces_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_image_mask_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_image_mask_frag.glsl index a1392abbb92..a1392abbb92 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_image_mask_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_image_mask_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_image_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_image_vert.glsl index 7ecbb513265..7ecbb513265 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_image_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_image_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_stretching_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_stretching_vert.glsl index bb086e8d9f5..bb086e8d9f5 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_stretching_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_stretching_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_tiled_image_borders_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_tiled_image_borders_vert.glsl index bc5235b9cab..bc5235b9cab 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_tiled_image_borders_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_tiled_image_borders_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_verts_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_frag.glsl index c0ea6aebe10..c0ea6aebe10 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_verts_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_verts_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl index 9f9b02ce19d..9f9b02ce19d 100644 --- a/source/blender/draw/engines/overlay/shaders/edit_uv_verts_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/extra_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_frag.glsl index bf29b2b057e..bf29b2b057e 100644 --- a/source/blender/draw/engines/overlay/shaders/extra_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/extra_groundline_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_groundline_vert.glsl index ff7aae523e7..ff7aae523e7 100644 --- a/source/blender/draw/engines/overlay/shaders/extra_groundline_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_groundline_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/extra_lightprobe_grid_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_lightprobe_grid_vert.glsl index 1eee7ab251b..1eee7ab251b 100644 --- a/source/blender/draw/engines/overlay/shaders/extra_lightprobe_grid_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_lightprobe_grid_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/extra_loose_point_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_loose_point_frag.glsl index d92b947ef89..d92b947ef89 100644 --- a/source/blender/draw/engines/overlay/shaders/extra_loose_point_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_loose_point_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/extra_loose_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_loose_point_vert.glsl index f283934816c..f283934816c 100644 --- a/source/blender/draw/engines/overlay/shaders/extra_loose_point_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_loose_point_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/extra_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl index de999c241c0..de999c241c0 100644 --- a/source/blender/draw/engines/overlay/shaders/extra_point_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/extra_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_vert.glsl index b2578970c9b..b2578970c9b 100644 --- a/source/blender/draw/engines/overlay/shaders/extra_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/extra_wire_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_wire_frag.glsl index f32e3a8564e..f32e3a8564e 100644 --- a/source/blender/draw/engines/overlay/shaders/extra_wire_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_wire_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/extra_wire_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_wire_vert.glsl index cd217021e8f..cd217021e8f 100644 --- a/source/blender/draw/engines/overlay/shaders/extra_wire_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_wire_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/facing_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_facing_frag.glsl index 8208689d113..8208689d113 100644 --- a/source/blender/draw/engines/overlay/shaders/facing_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_facing_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/facing_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_facing_vert.glsl index d98caee6a25..d98caee6a25 100644 --- a/source/blender/draw/engines/overlay/shaders/facing_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_facing_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/grid_background_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_grid_background_frag.glsl index 37958319b44..37958319b44 100644 --- a/source/blender/draw/engines/overlay/shaders/grid_background_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_grid_background_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl index 25f4984f119..25f4984f119 100644 --- a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_grid_vert.glsl index b81f1a24358..b81f1a24358 100644 --- a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_grid_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/image_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_image_frag.glsl index e0339507e0f..e0339507e0f 100644 --- a/source/blender/draw/engines/overlay/shaders/image_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_image_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/image_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_image_vert.glsl index 45cddb3610d..45cddb3610d 100644 --- a/source/blender/draw/engines/overlay/shaders/image_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_image_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/motion_path_line_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_frag.glsl index 324d22501f9..324d22501f9 100644 --- a/source/blender/draw/engines/overlay/shaders/motion_path_line_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/motion_path_line_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_geom.glsl index 29346a44863..29346a44863 100644 --- a/source/blender/draw/engines/overlay/shaders/motion_path_line_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_geom.glsl diff --git a/source/blender/draw/engines/overlay/shaders/motion_path_line_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert.glsl index bc74a436f5e..bc74a436f5e 100644 --- a/source/blender/draw/engines/overlay/shaders/motion_path_line_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/motion_path_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_point_vert.glsl index 5027525b9b3..5027525b9b3 100644 --- a/source/blender/draw/engines/overlay/shaders/motion_path_point_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_point_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/outline_detect_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_detect_frag.glsl index 472a589f441..472a589f441 100644 --- a/source/blender/draw/engines/overlay/shaders/outline_detect_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_detect_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/outline_prepass_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_frag.glsl index d1abd74a7b3..d1abd74a7b3 100644 --- a/source/blender/draw/engines/overlay/shaders/outline_prepass_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/outline_prepass_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_geom.glsl index 8a196620af9..8a196620af9 100644 --- a/source/blender/draw/engines/overlay/shaders/outline_prepass_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_geom.glsl diff --git a/source/blender/draw/engines/overlay/shaders/outline_prepass_gpencil_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_frag.glsl index b6d5cd96c12..b6d5cd96c12 100644 --- a/source/blender/draw/engines/overlay/shaders/outline_prepass_gpencil_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/outline_prepass_gpencil_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_vert.glsl index 4b1470e5723..4b1470e5723 100644 --- a/source/blender/draw/engines/overlay/shaders/outline_prepass_gpencil_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_gpencil_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/outline_prepass_pointcloud_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_pointcloud_vert.glsl index 371ff628c59..371ff628c59 100644 --- a/source/blender/draw/engines/overlay/shaders/outline_prepass_pointcloud_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_pointcloud_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/outline_prepass_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_vert.glsl index 1d0b08f51b2..1d0b08f51b2 100644 --- a/source/blender/draw/engines/overlay/shaders/outline_prepass_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_prepass_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/paint_face_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_face_vert.glsl index 22906bf1526..22906bf1526 100644 --- a/source/blender/draw/engines/overlay/shaders/paint_face_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_face_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/paint_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_point_vert.glsl index 8736b2a87db..8736b2a87db 100644 --- a/source/blender/draw/engines/overlay/shaders/paint_point_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_point_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/paint_texture_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_texture_frag.glsl index e5af0e7bd88..e5af0e7bd88 100644 --- a/source/blender/draw/engines/overlay/shaders/paint_texture_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_texture_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/paint_texture_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_texture_vert.glsl index f93d0050950..f93d0050950 100644 --- a/source/blender/draw/engines/overlay/shaders/paint_texture_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_texture_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/paint_vertcol_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_vertcol_frag.glsl index 193fabc65cb..193fabc65cb 100644 --- a/source/blender/draw/engines/overlay/shaders/paint_vertcol_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_vertcol_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/paint_vertcol_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_vertcol_vert.glsl index 650070dcfd5..650070dcfd5 100644 --- a/source/blender/draw/engines/overlay/shaders/paint_vertcol_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_vertcol_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/paint_weight_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_weight_frag.glsl index 1befe7506c4..1befe7506c4 100644 --- a/source/blender/draw/engines/overlay/shaders/paint_weight_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_weight_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/paint_weight_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_weight_vert.glsl index cff79d606d6..cff79d606d6 100644 --- a/source/blender/draw/engines/overlay/shaders/paint_weight_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_weight_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/paint_wire_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_wire_vert.glsl index 749cc92f082..749cc92f082 100644 --- a/source/blender/draw/engines/overlay/shaders/paint_wire_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_wire_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/particle_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_particle_frag.glsl index a2bcca7b820..a2bcca7b820 100644 --- a/source/blender/draw/engines/overlay/shaders/particle_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_particle_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/particle_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl index fb981a8167a..fb981a8167a 100644 --- a/source/blender/draw/engines/overlay/shaders/particle_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/overlay_point_varying_color_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_point_varying_color_frag.glsl new file mode 100644 index 00000000000..4962fb01c88 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_point_varying_color_frag.glsl @@ -0,0 +1,23 @@ + +void main() +{ + vec2 centered = gl_PointCoord - vec2(0.5); + float dist_squared = dot(centered, centered); + const float rad_squared = 0.25; + + // round point with jaggy edges + if (dist_squared > rad_squared) { + discard; + } + +#if defined(VERT) + fragColor = finalColor; + + float midStroke = 0.5 * rad_squared; + if (vertexCrease > 0.0 && dist_squared > midStroke) { + fragColor.rgb = mix(finalColor.rgb, colorEdgeCrease.rgb, vertexCrease); + } +#else + fragColor = finalColor; +#endif +} diff --git a/source/blender/draw/engines/overlay/shaders/overlay_point_varying_color_varying_outline_aa_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_point_varying_color_varying_outline_aa_frag.glsl new file mode 100644 index 00000000000..c0ea6aebe10 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_point_varying_color_varying_outline_aa_frag.glsl @@ -0,0 +1,27 @@ + +void main() +{ + float dist = length(gl_PointCoord - vec2(0.5)); + + /* transparent outside of point + * --- 0 --- + * smooth transition + * --- 1 --- + * pure outline color + * --- 2 --- + * smooth transition + * --- 3 --- + * pure fill color + * ... + * dist = 0 at center of point */ + + float midStroke = 0.5 * (radii[1] + radii[2]); + + if (dist > midStroke) { + fragColor.rgb = outlineColor.rgb; + fragColor.a = mix(outlineColor.a, 0.0, smoothstep(radii[1], radii[0], dist)); + } + else { + fragColor = mix(fillColor, outlineColor, smoothstep(radii[3], radii[2], dist)); + } +} diff --git a/source/blender/draw/engines/overlay/shaders/sculpt_mask_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_sculpt_mask_frag.glsl index 9650af755c5..9650af755c5 100644 --- a/source/blender/draw/engines/overlay/shaders/sculpt_mask_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_sculpt_mask_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/sculpt_mask_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_sculpt_mask_vert.glsl index 36c0e6a0acf..36c0e6a0acf 100644 --- a/source/blender/draw/engines/overlay/shaders/sculpt_mask_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_sculpt_mask_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl new file mode 100644 index 00000000000..0a498471b46 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl @@ -0,0 +1,4 @@ +void main() +{ + fragColor = color; +}
\ No newline at end of file diff --git a/source/blender/draw/engines/overlay/shaders/overlay_varying_color.glsl b/source/blender/draw/engines/overlay/shaders/overlay_varying_color.glsl new file mode 100644 index 00000000000..a27e2849bb3 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_varying_color.glsl @@ -0,0 +1,4 @@ +void main() +{ + fragColor = finalColor; +} diff --git a/source/blender/draw/engines/overlay/shaders/volume_gridlines_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_volume_gridlines_vert.glsl index 11a04dddd2a..11a04dddd2a 100644 --- a/source/blender/draw/engines/overlay/shaders/volume_gridlines_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_volume_gridlines_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/volume_velocity_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_volume_velocity_vert.glsl index a33d27676c3..a33d27676c3 100644 --- a/source/blender/draw/engines/overlay/shaders/volume_velocity_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_volume_velocity_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/wireframe_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_wireframe_frag.glsl index bc28d7a8a36..bc28d7a8a36 100644 --- a/source/blender/draw/engines/overlay/shaders/wireframe_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_wireframe_frag.glsl diff --git a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_wireframe_vert.glsl index 41bd7791dd7..41bd7791dd7 100644 --- a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_wireframe_vert.glsl diff --git a/source/blender/draw/engines/overlay/shaders/xray_fade_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_xray_fade_frag.glsl index 9aa2fdc3796..9aa2fdc3796 100644 --- a/source/blender/draw/engines/overlay/shaders/xray_fade_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_xray_fade_frag.glsl diff --git a/source/blender/draw/intern/draw_attributes.cc b/source/blender/draw/intern/draw_attributes.cc index 714f1dbb3d1..f84a6c86fac 100644 --- a/source/blender/draw/intern/draw_attributes.cc +++ b/source/blender/draw/intern/draw_attributes.cc @@ -65,9 +65,9 @@ bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b) } DRW_AttributeRequest *drw_attributes_add_request(DRW_Attributes *attrs, - CustomDataType type, + eCustomDataType type, int layer, - AttributeDomain domain) + eAttrDomain domain) { if (attrs->num_requests >= GPU_MAX_ATTR) { return nullptr; diff --git a/source/blender/draw/intern/draw_attributes.h b/source/blender/draw/intern/draw_attributes.h index 192ffa43337..c375670cd70 100644 --- a/source/blender/draw/intern/draw_attributes.h +++ b/source/blender/draw/intern/draw_attributes.h @@ -25,9 +25,9 @@ extern "C" { #endif typedef struct DRW_AttributeRequest { - CustomDataType cd_type; + eCustomDataType cd_type; int layer_index; - AttributeDomain domain; + eAttrDomain domain; char attribute_name[64]; } DRW_AttributeRequest; @@ -46,9 +46,9 @@ void drw_attributes_merge(DRW_Attributes *dst, bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b); DRW_AttributeRequest *drw_attributes_add_request(DRW_Attributes *attrs, - CustomDataType type, + eCustomDataType type, int layer, - AttributeDomain domain); + eAttrDomain domain); bool drw_custom_data_match_attribute(const CustomData *custom_data, const char *name, diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index f9cf0021fcd..68f210105b0 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -514,7 +514,7 @@ static bool curves_ensure_attributes(const Curves &curves, const char *name = gpu_attr->name; int type = gpu_attr->type; int layer = -1; - AttributeDomain domain; + eAttrDomain domain; if (drw_custom_data_match_attribute(cd_curve, name, &layer, &type)) { domain = ATTR_DOMAIN_CURVE; @@ -538,7 +538,7 @@ static bool curves_ensure_attributes(const Curves &curves, case CD_PROP_COLOR: { if (layer != -1) { DRW_AttributeRequest *req = drw_attributes_add_request( - &attrs_needed, (CustomDataType)type, layer, domain); + &attrs_needed, (eCustomDataType)type, layer, domain); if (req) { BLI_strncpy(req->attribute_name, name, sizeof(req->attribute_name)); } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index a6ab2176d16..a7fd484c72f 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -396,7 +396,7 @@ static uint mesh_cd_calc_gpu_layers_vcol_used(const Mesh *me_query, const char name[]) { CustomDataLayer *layer = NULL; - AttributeDomain domain; + eAttrDomain domain; if (name[0]) { int layer_i = 0; @@ -469,7 +469,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, int type = gpu_attr->type; int layer = -1; /* ATTR_DOMAIN_NUM is standard for "invalid value". */ - AttributeDomain domain = ATTR_DOMAIN_NUM; + eAttrDomain domain = ATTR_DOMAIN_NUM; if (type == CD_AUTO_FROM_NAME) { /* We need to deduce what exact layer is used. diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index ef2a097ad8e..0b523eb3be8 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -221,7 +221,7 @@ static GPUShader *get_patch_evaluation_shader(int shader_type) "#define OSD_PATCH_BASIS_GLSL\n" "#define OPENSUBDIV_GLSL_COMPUTE_USE_1ST_DERIVATIVES\n" "#define FDOTS_EVALUATION\n" - "#define FOTS_NORMALS\n"; + "#define FDOTS_NORMALS\n"; } else if (shader_type == SHADER_PATCH_EVALUATION_ORCO) { defines = @@ -575,6 +575,7 @@ static void draw_subdiv_free_edit_mode_cache(DRWSubdivCache *cache) void draw_subdiv_cache_free(DRWSubdivCache *cache) { GPU_VERTBUF_DISCARD_SAFE(cache->patch_coords); + GPU_VERTBUF_DISCARD_SAFE(cache->corner_patch_coords); GPU_VERTBUF_DISCARD_SAFE(cache->face_ptex_offset_buffer); GPU_VERTBUF_DISCARD_SAFE(cache->subdiv_polygon_offset_buffer); GPU_VERTBUF_DISCARD_SAFE(cache->extra_coarse_face_data); @@ -782,7 +783,7 @@ struct DRWCacheBuildingContext { DRWSubdivCache *cache; - /* Pointers into DRWSubdivCache buffers for easier access during traversal. */ + /* Pointers into #DRWSubdivCache buffers for easier access during traversal. */ CompressedPatchCoord *patch_coords; int *subdiv_loop_vert_index; int *subdiv_loop_subdiv_vert_index; @@ -794,9 +795,9 @@ struct DRWCacheBuildingContext { int *vert_origindex_map; int *edge_origindex_map; - /* Origindex layers from the mesh to directly look up during traversal the origindex from the - * base mesh for edit data so that we do not have to handle yet another GPU buffer and do this in - * the shaders. */ + /* #CD_ORIGINDEX layers from the mesh to directly look up during traversal the original-index + * from the base mesh for edit data so that we do not have to handle yet another GPU buffer and + * do this in the shaders. */ const int *v_origindex; const int *e_origindex; }; @@ -836,6 +837,11 @@ static bool draw_subdiv_topology_info_cb(const SubdivForeachContext *foreach_con cache->patch_coords, get_blender_patch_coords_format(), GPU_USAGE_DYNAMIC); GPU_vertbuf_data_alloc(cache->patch_coords, cache->num_subdiv_loops); + cache->corner_patch_coords = GPU_vertbuf_calloc(); + GPU_vertbuf_init_with_format_ex( + cache->corner_patch_coords, get_blender_patch_coords_format(), GPU_USAGE_DYNAMIC); + GPU_vertbuf_data_alloc(cache->corner_patch_coords, cache->num_subdiv_loops); + cache->verts_orig_index = GPU_vertbuf_calloc(); GPU_vertbuf_init_with_format_ex( cache->verts_orig_index, get_origindex_format(), GPU_USAGE_DYNAMIC); @@ -1131,6 +1137,12 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache, * the mesh to not be watertight, leading to shadowing artifacts (see T97877). */ blender::Vector<int> first_loop_index(cache->num_subdiv_verts, -1); + /* Save coordinates for corners, as attributes may vary for each loop connected to the same + * vertex. */ + memcpy(GPU_vertbuf_get_data(cache->corner_patch_coords), + cache_building_context.patch_coords, + sizeof(CompressedPatchCoord) * cache->num_subdiv_loops); + for (int i = 0; i < cache->num_subdiv_loops; i++) { const int vertex = cache_building_context.subdiv_loop_subdiv_vert_index[i]; if (first_loop_index[vertex] != -1) { @@ -1426,7 +1438,7 @@ void draw_subdiv_extract_uvs(const DRWSubdivCache *cache, GPU_vertbuf_bind_as_ssbo(src_buffer, binding_point++); GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_handles, binding_point++); GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_quadtree, binding_point++); - GPU_vertbuf_bind_as_ssbo(cache->patch_coords, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->corner_patch_coords, binding_point++); GPU_vertbuf_bind_as_ssbo(cache->verts_orig_index, binding_point++); GPU_vertbuf_bind_as_ssbo(patch_arrays_buffer, binding_point++); GPU_vertbuf_bind_as_ssbo(patch_index_buffer, binding_point++); @@ -1501,7 +1513,7 @@ void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache, GPU_vertbuf_bind_as_ssbo(cache->subdiv_polygon_offset_buffer, binding_point++); GPU_vertbuf_bind_as_ssbo(src_data, binding_point++); GPU_vertbuf_bind_as_ssbo(cache->face_ptex_offset_buffer, binding_point++); - GPU_vertbuf_bind_as_ssbo(cache->patch_coords, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->corner_patch_coords, binding_point++); GPU_vertbuf_bind_as_ssbo(cache->extra_coarse_face_data, binding_point++); GPU_vertbuf_bind_as_ssbo(dst_data, binding_point++); BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS); diff --git a/source/blender/draw/intern/draw_subdivision.h b/source/blender/draw/intern/draw_subdivision.h index 15c770a51c4..8920a2dcd51 100644 --- a/source/blender/draw/intern/draw_subdivision.h +++ b/source/blender/draw/intern/draw_subdivision.h @@ -104,8 +104,10 @@ typedef struct DRWSubdivCache { bool optimal_display; bool use_custom_loop_normals; - /* Coordinates used to evaluate patches for UVs, positions, and normals. */ + /* Coordinates used to evaluate patches for positions and normals. */ struct GPUVertBuf *patch_coords; + /* Coordinates used to evaluate patches for attributes. */ + struct GPUVertBuf *corner_patch_coords; /* Coordinates used to evaluate patches for the face centers (or face dots) in edit-mode. */ struct GPUVertBuf *fdots_patch_coords; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc index d595abc6dd3..fa41facb751 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc @@ -24,7 +24,7 @@ namespace blender::draw { /** \name Extract Attributes * \{ */ -static CustomData *get_custom_data_for_domain(const MeshRenderData *mr, AttributeDomain domain) +static CustomData *get_custom_data_for_domain(const MeshRenderData *mr, eAttrDomain domain) { switch (domain) { default: { @@ -80,7 +80,7 @@ template<> struct attribute_type_converter<MPropCol, gpuMeshCol> { }; /* Return the number of component for the attribute's value type, or 0 if is it unsupported. */ -static uint gpu_component_size_for_attribute_type(CustomDataType type) +static uint gpu_component_size_for_attribute_type(eCustomDataType type) { switch (type) { case CD_PROP_BOOL: @@ -106,7 +106,7 @@ static uint gpu_component_size_for_attribute_type(CustomDataType type) } } -static GPUVertFetchMode get_fetch_mode_for_type(CustomDataType type) +static GPUVertFetchMode get_fetch_mode_for_type(eCustomDataType type) { switch (type) { case CD_PROP_INT32: { @@ -121,7 +121,7 @@ static GPUVertFetchMode get_fetch_mode_for_type(CustomDataType type) } } -static GPUVertCompType get_comp_type_for_type(CustomDataType type) +static GPUVertCompType get_comp_type_for_type(eCustomDataType type) { switch (type) { case CD_PROP_INT32: { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc index fa5bf35198b..91ac3f22617 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc @@ -16,7 +16,7 @@ struct VColRef { const CustomDataLayer *layer; - AttributeDomain domain; + eAttrDomain domain; }; /** Get all vcol layers as AttributeRefs. @@ -32,7 +32,7 @@ static blender::Vector<VColRef> get_vcol_refs(const CustomData *cd_vdata, blender::Vector<VColRef> refs; uint layeri = 0; - auto buildList = [&](const CustomData *cdata, AttributeDomain domain) { + auto buildList = [&](const CustomData *cdata, eAttrDomain domain) { for (int i = 0; i < cdata->totlayer; i++) { const CustomDataLayer *layer = cdata->layers + i; @@ -111,7 +111,7 @@ static GPUVertFormat *get_coarse_vcol_format() { static GPUVertFormat format = {0}; if (format.attr_len == 0) { - GPU_vertformat_attr_add(&format, "cCol", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + GPU_vertformat_attr_add(&format, "cCol", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); GPU_vertformat_alias_add(&format, "c"); GPU_vertformat_alias_add(&format, "ac"); } @@ -245,6 +245,7 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache, &coarse_mesh->vdata; const CustomData *cd_ldata = extract_bmesh ? &coarse_mesh->edit_mesh->bm->ldata : &coarse_mesh->ldata; + const int totloop = extract_bmesh ? coarse_mesh->edit_mesh->bm->totloop : coarse_mesh->totloop; Mesh me_query = blender::dna::shallow_copy(*coarse_mesh); BKE_id_attribute_copy_domains_temp( @@ -263,7 +264,7 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache, /* Dynamic as we upload and interpolate layers one at a time. */ GPU_vertbuf_init_with_format_ex(src_data, get_coarse_vcol_format(), GPU_USAGE_DYNAMIC); - GPU_vertbuf_data_alloc(src_data, coarse_mesh->totloop); + GPU_vertbuf_data_alloc(src_data, totloop); gpuMeshVcol *mesh_vcol = (gpuMeshVcol *)GPU_vertbuf_get_data(src_data); @@ -279,8 +280,6 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache, const int dst_offset = (int)subdiv_cache->num_subdiv_loops * 2 * pack_layer_index++; const CustomData *cdata = ref.domain == ATTR_DOMAIN_POINT ? cd_vdata : cd_ldata; - const MLoop *ml = coarse_mesh->mloop; - int layer_i = CustomData_get_named_layer_index(cdata, ref.layer->type, ref.layer->name); if (layer_i == -1) { @@ -289,15 +288,6 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache, } gpuMeshVcol *vcol = mesh_vcol; - MLoopCol *mcol = nullptr; - MPropCol *pcol = nullptr; - - if (ref.layer->type == CD_PROP_COLOR) { - pcol = static_cast<MPropCol *>(cdata->layers[layer_i].data); - } - else { - mcol = static_cast<MLoopCol *>(cdata->layers[layer_i].data); - } const bool is_vert = ref.domain == ATTR_DOMAIN_POINT; @@ -331,10 +321,23 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache, vcol->b = unit_float_to_ushort_clamp(pcol2->color[2]); vcol->a = unit_float_to_ushort_clamp(pcol2->color[3]); } + + vcol++; } while ((l_iter = l_iter->next) != f->l_first); } } else { + const MLoop *ml = coarse_mesh->mloop; + MLoopCol *mcol = nullptr; + MPropCol *pcol = nullptr; + + if (ref.layer->type == CD_PROP_COLOR) { + pcol = static_cast<MPropCol *>(cdata->layers[layer_i].data); + } + else { + mcol = static_cast<MLoopCol *>(cdata->layers[layer_i].data); + } + for (int ml_index = 0; ml_index < coarse_mesh->totloop; ml_index++, vcol++, ml++) { int idx = is_vert ? ml->v : ml_index; diff --git a/source/blender/draw/intern/shaders/common_hair_lib.glsl b/source/blender/draw/intern/shaders/common_hair_lib.glsl index dfa2f307800..e235da91e8d 100644 --- a/source/blender/draw/intern/shaders/common_hair_lib.glsl +++ b/source/blender/draw/intern/shaders/common_hair_lib.glsl @@ -5,6 +5,8 @@ * of data the CPU has to precompute and transfer for each update. */ +#define COMMON_HAIR_LIB + /* TODO(fclem): Keep documentation but remove the uniform declaration. */ #ifndef USE_GPU_SHADER_CREATE_INFO diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index f9b973733af..5ef001812ab 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -375,13 +375,10 @@ static void updateDuplicateSubtarget(EditBone *dup_bone, /* does this constraint have a subtarget in * this armature? */ - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(curcon, &targets); - + if (BKE_constraint_targets_get(curcon, &targets)) { for (ct = targets.first; ct; ct = ct->next) { if ((ct->tar == ob) && (ct->subtarget[0])) { oldtarget = get_named_editbone(editbones, ct->subtarget); @@ -409,9 +406,7 @@ static void updateDuplicateSubtarget(EditBone *dup_bone, } } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(curcon, &targets, 0); - } + BKE_constraint_targets_flush(curcon, &targets, 0); } } } diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c index e1f2605481f..1f02e24666d 100644 --- a/source/blender/editors/armature/armature_naming.c +++ b/source/blender/editors/armature/armature_naming.c @@ -109,13 +109,10 @@ static void constraint_bone_name_fix(Object *ob, bConstraintTarget *ct; for (curcon = conlist->first; curcon; curcon = curcon->next) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon); ListBase targets = {NULL, NULL}; /* constraint targets */ - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(curcon, &targets); - + if (BKE_constraint_targets_get(curcon, &targets)) { for (ct = targets.first; ct; ct = ct->next) { if (ct->tar == ob) { if (STREQ(ct->subtarget, oldname)) { @@ -124,9 +121,7 @@ static void constraint_bone_name_fix(Object *ob, } } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(curcon, &targets, 0); - } + BKE_constraint_targets_flush(curcon, &targets, 0); } /* action constraints */ diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index be4829c02be..950178e865d 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -68,14 +68,11 @@ static void joined_armature_fix_links_constraints(Main *bmain, bool changed = false; for (con = lb->first; con; con = con->next) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; /* constraint targets */ - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); - + if (BKE_constraint_targets_get(con, &targets)) { for (ct = targets.first; ct; ct = ct->next) { if (ct->tar == srcArm) { if (ct->subtarget[0] == '\0') { @@ -90,9 +87,7 @@ static void joined_armature_fix_links_constraints(Main *bmain, } } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, 0); - } + BKE_constraint_targets_flush(con, &targets, 0); } /* action constraint? (pose constraints only) */ @@ -459,14 +454,11 @@ static void separated_armature_fix_links(Main *bmain, Object *origArm, Object *n if (ob->type == OB_ARMATURE) { for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { for (con = pchan->constraints.first; con; con = con->next) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; /* constraint targets */ - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); - + if (BKE_constraint_targets_get(con, &targets)) { for (ct = targets.first; ct; ct = ct->next) { /* Any targets which point to original armature * are redirected to the new one only if: @@ -487,9 +479,7 @@ static void separated_armature_fix_links(Main *bmain, Object *origArm, Object *n } } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, 0); - } + BKE_constraint_targets_flush(con, &targets, 0); } } } @@ -498,14 +488,11 @@ static void separated_armature_fix_links(Main *bmain, Object *origArm, Object *n /* fix object-level constraints */ if (ob != origArm) { for (con = ob->constraints.first; con; con = con->next) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; /* constraint targets */ - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); - + if (BKE_constraint_targets_get(con, &targets)) { for (ct = targets.first; ct; ct = ct->next) { /* any targets which point to original armature are redirected to the new one only if: * - the target isn't origArm/newArm itself @@ -525,9 +512,7 @@ static void separated_armature_fix_links(Main *bmain, Object *origArm, Object *n } } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, 0); - } + BKE_constraint_targets_flush(con, &targets, 0); } } } diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index 8790a10f3e5..b6b5d3ee495 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -680,13 +680,10 @@ static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones) { if (pchan->bone->flag & BONE_SELECTED) { for (con = pchan->constraints.first; con; con = con->next) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); - + if (BKE_constraint_targets_get(con, &targets)) { for (ct = targets.first; ct; ct = ct->next) { Object *ob = ct->tar; @@ -702,9 +699,7 @@ static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op } } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, 1); - } + BKE_constraint_targets_flush(con, &targets, 1); } } } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 9da9845116d..dc49a5ed531 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -4729,6 +4729,7 @@ void CURVE_OT_make_segment(wmOperatorType *ot) bool ED_curve_editnurb_select_pick(bContext *C, const int mval[2], const int dist_px, + const bool vert_without_handles, const struct SelectPick_Params *params) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); @@ -4744,6 +4745,9 @@ bool ED_curve_editnurb_select_pick(bContext *C, ED_view3d_viewcontext_init(C, &vc, depsgraph); copy_v2_v2_int(vc.mval, mval); + const bool use_handle_select = vert_without_handles && + (vc.v3d->overlay.handle_display != CURVE_HANDLE_NONE); + bool found = ED_curve_pick_vert_ex(&vc, 1, dist_px, &nu, &bezt, &bp, &hand, &basact); if (params->sel_op == SEL_OP_SET) { @@ -4779,7 +4783,12 @@ bool ED_curve_editnurb_select_pick(bContext *C, case SEL_OP_ADD: { if (bezt) { if (hand == 1) { - select_beztriple(bezt, SELECT, SELECT, HIDDEN); + if (use_handle_select) { + bezt->f2 |= SELECT; + } + else { + select_beztriple(bezt, SELECT, SELECT, HIDDEN); + } } else { if (hand == 0) { @@ -4800,7 +4809,12 @@ bool ED_curve_editnurb_select_pick(bContext *C, case SEL_OP_SUB: { if (bezt) { if (hand == 1) { - select_beztriple(bezt, DESELECT, SELECT, HIDDEN); + if (use_handle_select) { + bezt->f2 &= ~SELECT; + } + else { + select_beztriple(bezt, DESELECT, SELECT, HIDDEN); + } if (bezt == vert) { cu->actvert = CU_ACT_NONE; } @@ -4824,13 +4838,23 @@ bool ED_curve_editnurb_select_pick(bContext *C, if (bezt) { if (hand == 1) { if (bezt->f2 & SELECT) { - select_beztriple(bezt, DESELECT, SELECT, HIDDEN); + if (use_handle_select) { + bezt->f2 &= ~SELECT; + } + else { + select_beztriple(bezt, DESELECT, SELECT, HIDDEN); + } if (bezt == vert) { cu->actvert = CU_ACT_NONE; } } else { - select_beztriple(bezt, SELECT, SELECT, HIDDEN); + if (use_handle_select) { + bezt->f2 |= SELECT; + } + else { + select_beztriple(bezt, SELECT, SELECT, HIDDEN); + } BKE_curve_nurb_vert_active_set(cu, nu, bezt); } } @@ -4861,7 +4885,12 @@ bool ED_curve_editnurb_select_pick(bContext *C, if (bezt) { if (hand == 1) { - select_beztriple(bezt, SELECT, SELECT, HIDDEN); + if (use_handle_select) { + bezt->f2 |= SELECT; + } + else { + select_beztriple(bezt, SELECT, SELECT, HIDDEN); + } } else { if (hand == 0) { diff --git a/source/blender/editors/curve/editcurve_pen.c b/source/blender/editors/curve/editcurve_pen.c index fca850076ae..a98b165e99d 100644 --- a/source/blender/editors/curve/editcurve_pen.c +++ b/source/blender/editors/curve/editcurve_pen.c @@ -1655,7 +1655,7 @@ static int curve_pen_modal(bContext *C, wmOperator *op, const wmEvent *event) else if (ELEM(event->type, LEFTMOUSE)) { if (ELEM(event->val, KM_RELEASE, KM_DBL_CLICK)) { if (delete_point && !cpd->new_point && !cpd->dragging) { - if (ED_curve_editnurb_select_pick(C, event->mval, threshold_dist_px, ¶ms)) { + if (ED_curve_editnurb_select_pick(C, event->mval, threshold_dist_px, false, ¶ms)) { cpd->acted = delete_point_under_mouse(&vc, event); } } @@ -1714,7 +1714,7 @@ static int curve_pen_modal(bContext *C, wmOperator *op, const wmEvent *event) } } else if (select_point) { - ED_curve_editnurb_select_pick(C, event->mval, threshold_dist_px, ¶ms); + ED_curve_editnurb_select_pick(C, event->mval, threshold_dist_px, false, ¶ms); } } diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 5588f7440a8..85214e1608d 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -6,18 +6,23 @@ #include <atomic> +#include "BLI_devirtualize_parameters.hh" #include "BLI_utildefines.h" +#include "BLI_vector_set.hh" #include "ED_curves.h" #include "ED_object.h" #include "ED_screen.h" +#include "ED_select_utils.h" #include "WM_api.h" #include "BKE_bvhutils.h" #include "BKE_context.h" #include "BKE_curves.hh" +#include "BKE_geometry_set.hh" #include "BKE_layer.h" +#include "BKE_lib_id.h" #include "BKE_mesh.h" #include "BKE_mesh_runtime.h" #include "BKE_object.h" @@ -37,6 +42,7 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "RNA_prototypes.h" /** @@ -49,6 +55,41 @@ namespace blender::ed::curves { +static bool object_has_editable_curves(const Main &bmain, const Object &object) +{ + if (object.type != OB_CURVES) { + return false; + } + if (!ELEM(object.mode, OB_MODE_SCULPT_CURVES, OB_MODE_EDIT)) { + return false; + } + if (!BKE_id_is_editable(&bmain, static_cast<const ID *>(object.data))) { + return false; + } + return true; +} + +static VectorSet<Curves *> get_unique_editable_curves(const bContext &C) +{ + VectorSet<Curves *> unique_curves; + + const Main &bmain = *CTX_data_main(&C); + + Object *object = CTX_data_active_object(&C); + if (object && object_has_editable_curves(bmain, *object)) { + unique_curves.add_new(static_cast<Curves *>(object->data)); + } + + CTX_DATA_BEGIN (&C, Object *, object, selected_objects) { + if (object_has_editable_curves(bmain, *object)) { + unique_curves.add(static_cast<Curves *>(object->data)); + } + } + CTX_DATA_END; + + return unique_curves; +} + using bke::CurvesGeometry; namespace convert_to_particle_system { @@ -193,7 +234,7 @@ static void try_convert_single_object(Object &curves_ob, /* The old hair system still uses #MFace, so make sure those are available on the mesh. */ BKE_mesh_tessface_calc(&surface_me); - /* Prepare utility data structure to map hair roots to mfaces. */ + /* Prepare utility data structure to map hair roots to #MFace's. */ const Span<int> mface_to_poly_map{ static_cast<const int *>(CustomData_get_layer(&surface_me.fdata, CD_ORIGINDEX)), surface_me.totface}; @@ -645,6 +686,222 @@ static void CURVES_OT_snap_curves_to_surface(wmOperatorType *ot) "How to find the point on the surface to attach to"); } +static bool selection_poll(bContext *C) +{ + const Object *object = CTX_data_active_object(C); + if (object == nullptr) { + return false; + } + if (object->type != OB_CURVES) { + return false; + } + if (!BKE_id_is_editable(CTX_data_main(C), static_cast<const ID *>(object->data))) { + return false; + } + return true; +} + +namespace set_selection_domain { + +static int curves_set_selection_domain_exec(bContext *C, wmOperator *op) +{ + const eAttrDomain domain = eAttrDomain(RNA_enum_get(op->ptr, "domain")); + + for (Curves *curves_id : get_unique_editable_curves(*C)) { + if (curves_id->selection_domain == domain && (curves_id->flag & CV_SCULPT_SELECTION_ENABLED)) { + continue; + } + + const eAttrDomain old_domain = eAttrDomain(curves_id->selection_domain); + curves_id->selection_domain = domain; + curves_id->flag |= CV_SCULPT_SELECTION_ENABLED; + + CurveComponent component; + component.replace(curves_id, GeometryOwnershipType::Editable); + CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); + + if (old_domain == ATTR_DOMAIN_POINT && domain == ATTR_DOMAIN_CURVE) { + VArray<float> curve_selection = curves.adapt_domain( + curves.selection_point_float(), ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE); + curve_selection.materialize(curves.selection_curve_float_for_write()); + component.attribute_try_delete(".selection_point_float"); + } + else if (old_domain == ATTR_DOMAIN_CURVE && domain == ATTR_DOMAIN_POINT) { + VArray<float> point_selection = curves.adapt_domain( + curves.selection_curve_float(), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); + point_selection.materialize(curves.selection_point_float_for_write()); + component.attribute_try_delete(".selection_curve_float"); + } + + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic + * attribute for now. */ + DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id); + } + + WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, nullptr); + + return OPERATOR_FINISHED; +} + +} // namespace set_selection_domain + +static void CURVES_OT_set_selection_domain(wmOperatorType *ot) +{ + PropertyRNA *prop; + + ot->name = "Set Select Mode"; + ot->idname = __func__; + ot->description = "Change the mode used for selection masking in curves sculpt mode"; + + ot->exec = set_selection_domain::curves_set_selection_domain_exec; + ot->poll = selection_poll; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = prop = RNA_def_enum( + ot->srna, "domain", rna_enum_attribute_curves_domain_items, 0, "Domain", ""); + RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE)); +} + +namespace disable_selection { + +static int curves_disable_selection_exec(bContext *C, wmOperator *UNUSED(op)) +{ + for (Curves *curves_id : get_unique_editable_curves(*C)) { + curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED; + + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic + * attribute for now. */ + DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id); + } + + WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, nullptr); + + return OPERATOR_FINISHED; +} + +} // namespace disable_selection + +static void CURVES_OT_disable_selection(wmOperatorType *ot) +{ + ot->name = "Disable Selection"; + ot->idname = __func__; + ot->description = "Disable the drawing of influence of selection in sculpt mode"; + + ot->exec = disable_selection::curves_disable_selection_exec; + ot->poll = selection_poll; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +namespace select_all { + +static bool varray_contains_nonzero(const VArray<float> &data) +{ + bool contains_nonzero = false; + devirtualize_varray(data, [&](const auto array) { + for (const int i : data.index_range()) { + if (array[i] != 0.0f) { + contains_nonzero = true; + break; + } + } + }); + return contains_nonzero; +} + +static bool any_point_selected(const CurvesGeometry &curves) +{ + return varray_contains_nonzero(curves.selection_point_float()); +} + +static bool any_point_selected(const Span<Curves *> curves_ids) +{ + for (const Curves *curves_id : curves_ids) { + if (any_point_selected(CurvesGeometry::wrap(curves_id->geometry))) { + return true; + } + } + return false; +} + +static void invert_selection(MutableSpan<float> selection) +{ + threading::parallel_for(selection.index_range(), 2048, [&](IndexRange range) { + for (const int i : range) { + selection[i] = 1.0f - selection[i]; + } + }); +} + +static int select_all_exec(bContext *C, wmOperator *op) +{ + int action = RNA_enum_get(op->ptr, "action"); + + VectorSet<Curves *> unique_curves = get_unique_editable_curves(*C); + + if (action == SEL_TOGGLE) { + action = any_point_selected(unique_curves) ? SEL_DESELECT : SEL_SELECT; + } + + for (Curves *curves_id : unique_curves) { + if (action == SEL_SELECT) { + /* The optimization to avoid storing the selection when everything is selected causes too + * many problems at the moment, since there is no proper visualization yet. Keep the code but + * disable it for now. */ +#if 0 + CurveComponent component; + component.replace(curves_id, GeometryOwnershipType::Editable); + component.attribute_try_delete(".selection_point_float"); + component.attribute_try_delete(".selection_curve_float"); +#else + CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); + MutableSpan<float> selection = curves_id->selection_domain == ATTR_DOMAIN_POINT ? + curves.selection_point_float_for_write() : + curves.selection_curve_float_for_write(); + selection.fill(1.0f); +#endif + } + else { + CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); + MutableSpan<float> selection = curves_id->selection_domain == ATTR_DOMAIN_POINT ? + curves.selection_point_float_for_write() : + curves.selection_curve_float_for_write(); + if (action == SEL_DESELECT) { + selection.fill(0.0f); + } + else if (action == SEL_INVERT) { + invert_selection(selection); + } + } + + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic + * attribute for now. */ + DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id); + } + + return OPERATOR_FINISHED; +} + +} // namespace select_all + +static void SCULPT_CURVES_OT_select_all(wmOperatorType *ot) +{ + ot->name = "(De)select All"; + ot->idname = __func__; + ot->description = "(De)select all control points"; + + ot->exec = select_all::select_all_exec; + ot->poll = selection_poll; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + WM_operator_properties_select_all(ot); +} + } // namespace blender::ed::curves void ED_operatortypes_curves() @@ -653,4 +910,7 @@ void ED_operatortypes_curves() WM_operatortype_append(CURVES_OT_convert_to_particle_system); WM_operatortype_append(CURVES_OT_convert_from_particle_system); WM_operatortype_append(CURVES_OT_snap_curves_to_surface); + WM_operatortype_append(CURVES_OT_set_selection_domain); + WM_operatortype_append(SCULPT_CURVES_OT_select_all); + WM_operatortype_append(CURVES_OT_disable_selection); } diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index ed16b8a903a..c9677da1af5 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -33,6 +33,7 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "ED_geometry.h" #include "ED_object.h" #include "geometry_intern.hh" @@ -89,8 +90,8 @@ static int geometry_attribute_add_exec(bContext *C, wmOperator *op) char name[MAX_NAME]; RNA_string_get(op->ptr, "name", name); - CustomDataType type = (CustomDataType)RNA_enum_get(op->ptr, "data_type"); - AttributeDomain domain = (AttributeDomain)RNA_enum_get(op->ptr, "domain"); + eCustomDataType type = (eCustomDataType)RNA_enum_get(op->ptr, "data_type"); + eAttrDomain domain = (eAttrDomain)RNA_enum_get(op->ptr, "domain"); CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, domain, op->reports); if (layer == nullptr) { @@ -218,8 +219,8 @@ static int geometry_color_attribute_add_exec(bContext *C, wmOperator *op) char name[MAX_NAME]; RNA_string_get(op->ptr, "name", name); - CustomDataType type = (CustomDataType)RNA_enum_get(op->ptr, "data_type"); - AttributeDomain domain = (AttributeDomain)RNA_enum_get(op->ptr, "domain"); + eCustomDataType type = (eCustomDataType)RNA_enum_get(op->ptr, "data_type"); + eAttrDomain domain = (eAttrDomain)RNA_enum_get(op->ptr, "domain"); CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, domain, op->reports); float color[4]; @@ -288,9 +289,8 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op) * 4. Create a new attribute based on the previously copied data. */ switch (mode) { case ConvertAttributeMode::Generic: { - const AttributeDomain dst_domain = static_cast<AttributeDomain>( - RNA_enum_get(op->ptr, "domain")); - const CustomDataType dst_type = static_cast<CustomDataType>( + const eAttrDomain dst_domain = static_cast<eAttrDomain>(RNA_enum_get(op->ptr, "domain")); + const eCustomDataType dst_type = static_cast<eCustomDataType>( RNA_enum_get(op->ptr, "data_type")); if (ELEM(dst_type, CD_PROP_STRING)) { @@ -572,3 +572,38 @@ void GEOMETRY_OT_attribute_convert(wmOperatorType *ot) } } // namespace blender::ed::geometry + +using blender::CPPType; +using blender::GVArray; + +bool ED_geometry_attribute_convert(Mesh *mesh, + const char *layer_name, + eCustomDataType old_type, + eAttrDomain old_domain, + eCustomDataType new_type, + eAttrDomain new_domain) +{ + CustomDataLayer *layer = BKE_id_attribute_find(&mesh->id, layer_name, old_type, old_domain); + const std::string name = layer->name; + + if (!layer) { + return false; + } + + MeshComponent mesh_component; + mesh_component.replace(mesh, GeometryOwnershipType::Editable); + GVArray src_varray = mesh_component.attribute_get_for_read(name, new_domain, new_type); + + const CPPType &cpp_type = src_varray.type(); + void *new_data = MEM_malloc_arrayN(src_varray.size(), cpp_type.size(), __func__); + src_varray.materialize_to_uninitialized(new_data); + mesh_component.attribute_try_delete(name); + mesh_component.attribute_try_create(name, new_domain, new_type, AttributeInitMove(new_data)); + + int *active_index = BKE_id_attributes_active_index_p(&mesh->id); + if (*active_index > 0) { + *active_index -= 1; + } + + return true; +} diff --git a/source/blender/editors/gizmo_library/geometry/geom_arrow_gizmo.c b/source/blender/editors/gizmo_library/geometry/geom_arrow_gizmo.c index 5b514e02099..429bf39234f 100644 --- a/source/blender/editors/gizmo_library/geometry/geom_arrow_gizmo.c +++ b/source/blender/editors/gizmo_library/geometry/geom_arrow_gizmo.c @@ -7,6 +7,8 @@ #include "../gizmo_geometry.h" +/* The numerical values in the `verts` array are used in arrow3d_gizmo.c + * If you change this mesh geometry, update the selection code also. */ static float verts[][3] = { {-0.000000, 0.012320, 0.000000}, {-0.000000, 0.012320, 0.974306}, {0.008711, 0.008711, 0.000000}, {0.008711, 0.008711, 0.974306}, diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c index a1fb0e205b1..0e7a8873965 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c @@ -50,10 +50,8 @@ /* to use custom arrows exported to geom_arrow_gizmo.c */ //#define USE_GIZMO_CUSTOM_ARROWS -/** Margins to add when selecting the arrow stem. */ -#define ARROW_SELECT_THRESHOLD_PX_STEM (5 * UI_DPI_FAC) -/** Margins to add when selecting the arrow head. */ -#define ARROW_SELECT_THRESHOLD_PX_HEAD (12 * UI_DPI_FAC) +/* Margin to add when selecting the arrow. */ +#define ARROW_SELECT_THRESHOLD_PX (5) typedef struct ArrowGizmo3D { wmGizmo gizmo; @@ -121,8 +119,8 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const }; if (draw_options & ED_GIZMO_ARROW_DRAW_FLAG_STEM) { - const float stem_width = (arrow->gizmo.line_width * U.pixelsize) + - (select ? ARROW_SELECT_THRESHOLD_PX_STEM : 0); + const float stem_width = arrow->gizmo.line_width * U.pixelsize + + (select ? ARROW_SELECT_THRESHOLD_PX * U.dpi_fac : 0); immUniform1f("lineWidth", stem_width); wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GPU_PRIM_LINE_STRIP); } @@ -134,7 +132,7 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const GPU_matrix_push(); - /* NOTE: ideally #ARROW_SELECT_THRESHOLD_PX_HEAD would be added here, however adding a + /* NOTE: ideally #ARROW_SELECT_THRESHOLD_PX would be added here, however adding a * margin in pixel space isn't so simple, nor is it as important as for the arrow stem. */ if (draw_style == ED_GIZMO_ARROW_STYLE_BOX) { const float size = 0.05f; @@ -223,9 +221,15 @@ static void gizmo_arrow_draw(const bContext *UNUSED(C), wmGizmo *gz) */ static int gizmo_arrow_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2]) { + /* This following values are based on manual inspection of `verts[]` defined in + * geom_arrow_gizmo.c */ + const float head_center_z = (0.974306f + 1.268098f) / 2; + const float head_geo_x = 0.051304f; + const float stem_geo_x = 0.012320f; + /* Project into 2D space since it simplifies pixel threshold tests. */ ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz; - const float arrow_length = RNA_float_get(arrow->gizmo.ptr, "length"); + const float arrow_length = RNA_float_get(arrow->gizmo.ptr, "length") * head_center_z; float matrix_final[4][4]; WM_gizmo_calc_matrix_final(gz, matrix_final); @@ -239,12 +243,15 @@ static int gizmo_arrow_test_select(bContext *UNUSED(C), wmGizmo *gz, const int m copy_v2_v2(arrow_end, co); } + const float scale_final = mat4_to_scale(matrix_final); + const float head_width = ARROW_SELECT_THRESHOLD_PX * scale_final * head_geo_x; + const float stem_width = ARROW_SELECT_THRESHOLD_PX * scale_final * stem_geo_x; + float select_threshold_base = gz->line_width * U.pixelsize; + const float mval_fl[2] = {UNPACK2(mval)}; - const float arrow_stem_threshold_px = ARROW_SELECT_THRESHOLD_PX_STEM; - const float arrow_head_threshold_px = ARROW_SELECT_THRESHOLD_PX_HEAD; /* Distance to arrow head. */ - if (len_squared_v2v2(mval_fl, arrow_end) < square_f(arrow_head_threshold_px)) { + if (len_squared_v2v2(mval_fl, arrow_end) < square_f(select_threshold_base + head_width)) { return 0; } @@ -253,8 +260,8 @@ static int gizmo_arrow_test_select(bContext *UNUSED(C), wmGizmo *gz, const int m const float lambda = closest_to_line_v2(co_isect, mval_fl, arrow_start, arrow_end); /* Clamp inside the line, to avoid overlapping with other gizmos, * especially around the start of the arrow. */ - if (lambda >= 0.0 && lambda <= 1.0) { - if (len_squared_v2v2(mval_fl, co_isect) < square_f(arrow_stem_threshold_px)) { + if (lambda >= 0.0f && lambda <= 1.0f) { + if (len_squared_v2v2(mval_fl, co_isect) < square_f(select_threshold_base + stem_width)) { return 0; } } diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index 4f9468cc9c4..0601d009bf7 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -1104,7 +1104,7 @@ static void gpencil_stroke_to_bezier(bContext *C, rad_fac, minmax_weights); - /* shift coord vects */ + /* Shift coord vectors. */ copy_v3_v3(p3d_prev, p3d_cur); copy_v3_v3(p3d_cur, p3d_next); diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 3c8e6d6e5f5..5028baf1589 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -1811,7 +1811,16 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op) } else { /* Create a new layer. */ - target_layer = BKE_gpencil_layer_addnew(gpd, "GP_Layer", true, false); + PropertyRNA *prop; + char name[128]; + prop = RNA_struct_find_property(op->ptr, "new_layer_name"); + if (RNA_property_is_set(op->ptr, prop)) { + RNA_property_string_get(op->ptr, prop, name); + } + else { + strcpy(name, "GP_Layer"); + } + target_layer = BKE_gpencil_layer_addnew(gpd, name, true, false); } if (target_layer == NULL) { @@ -1888,8 +1897,46 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static void layer_new_name_get(bGPdata *gpd, char *rname) +{ + int index = 0; + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + if (strstr(gpl->info, "GP_Layer")) { + index++; + } + } + + if (index == 0) { + BLI_strncpy(rname, "GP_Layer", 128); + return; + } + char *name = BLI_sprintfN("%.*s.%03d", 128, "GP_Layer", index); + BLI_strncpy(rname, name, 128); + MEM_freeN(name); +} + +static int gpencil_move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + Object *ob = CTX_data_active_object(C); + PropertyRNA *prop; + if (RNA_int_get(op->ptr, "layer") == -1) { + prop = RNA_struct_find_property(op->ptr, "new_layer_name"); + if (!RNA_property_is_set(op->ptr, prop)) { + char name[MAX_NAME]; + bGPdata *gpd = ob->data; + layer_new_name_get(gpd, name); + RNA_property_string_set(op->ptr, prop, name); + return WM_operator_props_dialog_popup(C, op, 200); + } + } + + return gpencil_move_to_layer_exec(C, op); +} + void GPENCIL_OT_move_to_layer(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Move Strokes to Layer"; ot->idname = "GPENCIL_OT_move_to_layer"; @@ -1898,15 +1945,20 @@ void GPENCIL_OT_move_to_layer(wmOperatorType *ot) /* callbacks */ ot->exec = gpencil_move_to_layer_exec; - ot->poll = gpencil_stroke_edit_poll; /* XXX? */ + ot->invoke = gpencil_move_to_layer_invoke; + ot->poll = gpencil_stroke_edit_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* GPencil layer to use. */ - ot->prop = RNA_def_int( - ot->srna, "layer", 0, -1, INT_MAX, "Grease Pencil Layer", "", -1, INT_MAX); - RNA_def_property_flag(ot->prop, PROP_HIDDEN | PROP_SKIP_SAVE); + prop = RNA_def_int(ot->srna, "layer", 0, -1, INT_MAX, "Grease Pencil Layer", "", -1, INT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + + prop = RNA_def_string( + ot->srna, "new_layer_name", NULL, MAX_NAME, "Name", "Name of the newly added layer"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + ot->prop = prop; } /** \} */ diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 56c94e4494d..d656241c463 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -726,16 +726,16 @@ struct GP_EditableStrokes_Iter { (void)0 /** - * Iterate over all editable editcurves in the current context, - * stopping on each usable layer + stroke + curve pair (i.e. gpl, gps and gpc) + * Iterate over all editable edit-curves in the current context, + * stopping on each usable layer + stroke + curve pair (i.e. `gpl`, `gps` and `gpc`) * to perform some operations on the curve. * * \param gpl: The identifier to use for the layer of the stroke being processed. - * Choose a suitable value to avoid name clashes. + * Choose a suitable value to avoid name clashes. * \param gps: The identifier to use for current stroke being processed. - * Choose a suitable value to avoid name clashes. + * Choose a suitable value to avoid name clashes. * \param gpc: The identifier to use for current editcurve being processed. - * Choose a suitable value to avoid name clashes. + * Choose a suitable value to avoid name clashes. */ #define GP_EDITABLE_CURVES_BEGIN(gpstroke_iter, C, gpl, gps, gpc) \ { \ diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c index 01ac02a9a1d..6d0848de36d 100644 --- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c +++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c @@ -829,7 +829,7 @@ static bool gpencil_brush_randomize_apply(tGP_BrushEditData *gso, mul_v2_fl(svec, fac); } - /* convert to dataspace */ + /* Convert to data-space. */ if (gps->flag & GP_STROKE_3DSPACE) { /* 3D: Project to 3D space */ bool flip; diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 23c385c1213..5e8610c6b81 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -525,7 +525,7 @@ bool ED_gpencil_stroke_can_use_direct(const ScrArea *area, const bGPDstroke *gps return (area->spacetype == SPACE_IMAGE); } if (gps->flag & GP_STROKE_2DSPACE) { - /* 2D strokes (dataspace) - for any 2D view (i.e. everything other than 3D view) */ + /* 2D strokes (data-space) - for any 2D view (i.e. everything other than 3D view). */ return (area->spacetype != SPACE_VIEW3D); } /* view aligned - anything goes */ diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index 3f1b8d6ecda..84512653a24 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -55,17 +55,17 @@ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin); * finished. */ void immDrawPixelsTexScaledFullSize(const IMMDrawPixelsTexState *state, - const float x, - const float y, - const int img_w, - const int img_h, - const eGPUTextureFormat gpu_format, - const bool use_filter, + float x, + float y, + int img_w, + int img_h, + eGPUTextureFormat gpu_format, + bool use_filter, const void *rect, - const float scaleX, - const float scaleY, - const float xzoom, - const float yzoom, + float scaleX, + float scaleY, + float xzoom, + float yzoom, const float color[4]); /** diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h index 9f4833bf1d7..061b783797d 100644 --- a/source/blender/editors/include/ED_curve.h +++ b/source/blender/editors/include/ED_curve.h @@ -49,10 +49,12 @@ void ED_curve_editnurb_free(struct Object *obedit); /** * \param dist_px: Maximum distance to pick (in pixels). + * \param vert_without_handles: When true, selecting the knot doesn't select the handles. */ bool ED_curve_editnurb_select_pick(struct bContext *C, const int mval[2], int dist_px, + bool vert_without_handles, const struct SelectPick_Params *params); struct Nurb *ED_curve_add_nurbs_primitive( diff --git a/source/blender/editors/include/ED_geometry.h b/source/blender/editors/include/ED_geometry.h index 74ff968828c..4620181894a 100644 --- a/source/blender/editors/include/ED_geometry.h +++ b/source/blender/editors/include/ED_geometry.h @@ -7,12 +7,22 @@ #pragma once +#include "BKE_attribute.h" +#include "DNA_customdata_types.h" + #ifdef __cplusplus extern "C" { #endif -void ED_operatortypes_geometry(void); +struct Mesh; +void ED_operatortypes_geometry(void); +bool ED_geometry_attribute_convert(struct Mesh *mesh, + const char *layer_name, + eCustomDataType old_type, + eAttrDomain old_domain, + eCustomDataType new_type, + eAttrDomain new_domain); #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index a9a9c98cab8..98c98f99d32 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1866,7 +1866,7 @@ struct PointerRNA *UI_region_panel_custom_data_under_cursor(const struct bContex const struct wmEvent *event); void UI_panel_custom_data_set(struct Panel *panel, struct PointerRNA *custom_data); -/* Polyinstantiated panels for representing a list of data. */ +/* Poly-instantiated panels for representing a list of data. */ /** * Called in situations where panels need to be added dynamically rather than * having only one panel corresponding to each #PanelType. diff --git a/source/blender/editors/interface/interface_eyedropper_datablock.c b/source/blender/editors/interface/interface_eyedropper_datablock.c index aec8f56678a..01b958576b6 100644 --- a/source/blender/editors/interface/interface_eyedropper_datablock.c +++ b/source/blender/editors/interface/interface_eyedropper_datablock.c @@ -156,7 +156,7 @@ static void datadropper_id_sample_pt( CTX_wm_area_set(C, area); CTX_wm_region_set(C, region); - /* grr, always draw else we leave stale text */ + /* Unfortunately it's necessary to always draw else we leave stale text. */ ED_region_tag_redraw(region); if (area->spacetype == SPACE_VIEW3D) { diff --git a/source/blender/editors/interface/interface_eyedropper_depth.c b/source/blender/editors/interface/interface_eyedropper_depth.c index 56bc1a6d956..3c6f127582a 100644 --- a/source/blender/editors/interface/interface_eyedropper_depth.c +++ b/source/blender/editors/interface/interface_eyedropper_depth.c @@ -171,7 +171,7 @@ static void depthdropper_depth_sample_pt(bContext *C, CTX_wm_area_set(C, area); CTX_wm_region_set(C, region); - /* grr, always draw else we leave stale text */ + /* Unfortunately it's necessary to always draw otherwise we leave stale text. */ ED_region_tag_redraw(region); view3d_operator_needs_opengl(C); diff --git a/source/blender/editors/interface/interface_template_attribute_search.cc b/source/blender/editors/interface/interface_template_attribute_search.cc index 65764e31ec8..4e587bd5338 100644 --- a/source/blender/editors/interface/interface_template_attribute_search.cc +++ b/source/blender/editors/interface/interface_template_attribute_search.cc @@ -24,14 +24,14 @@ using blender::nodes::geometry_nodes_eval_log::GeometryAttributeInfo; namespace blender::ui { -static StringRef attribute_data_type_string(const CustomDataType type) +static StringRef attribute_data_type_string(const eCustomDataType type) { const char *name = nullptr; RNA_enum_name_from_value(rna_enum_attribute_type_items, type, &name); return StringRef(IFACE_(name)); } -static StringRef attribute_domain_string(const AttributeDomain domain) +static StringRef attribute_domain_string(const eAttrDomain domain) { const char *name = nullptr; RNA_enum_name_from_value(rna_enum_attribute_domain_items, domain, &name); diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c index 609230eefea..8a24b48be5e 100644 --- a/source/blender/editors/io/io_usd.c +++ b/source/blender/editors/io/io_usd.c @@ -217,6 +217,7 @@ void WM_OT_usd_export(struct wmOperatorType *ot) ot->check = wm_usd_export_check; ot->flag = OPTYPE_REGISTER; /* No UNDO possible. */ + ot->flag |= OPTYPE_PRESET; WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_USD, diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc index 41af8bcfef5..9e28dbcb803 100644 --- a/source/blender/editors/mesh/editface.cc +++ b/source/blender/editors/mesh/editface.cc @@ -182,7 +182,7 @@ void paintface_reveal(bContext *C, Object *ob, const bool select) paintface_flush_flags(C, ob, SELECT, true); } -/* Set tface seams based on edge data, uses hash table to find seam edges. */ +/* Set object-mode face selection seams based on edge data, uses hash table to find seam edges. */ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bool select) { diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 5b3487b0a33..c16b82e34bd 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -4672,6 +4672,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) case MOUSEMOVE: /* Mouse moved somewhere to select another loop. */ if (kcd->mode != MODE_PANNING) { knifetool_update_mval_i(kcd, event->mval); + knife_update_header(C, op, kcd); if (kcd->is_drag_hold) { if (kcd->totlinehit >= 2) { @@ -4754,6 +4755,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) /* We don't really need to update mval, * but this happens to be the best way to refresh at the moment. */ knifetool_update_mval_i(kcd, event->mval); + knife_update_header(C, op, kcd); } /* Keep going until the user confirms. */ diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c index ecc5f8f8ef5..d75c92f963f 100644 --- a/source/blender/editors/mesh/editmesh_undo.c +++ b/source/blender/editors/mesh/editmesh_undo.c @@ -72,7 +72,7 @@ static CLG_LogRef LOG = {"ed.undo.mesh"}; /* Single linked list of layers stored per type */ typedef struct BArrayCustomData { struct BArrayCustomData *next; - CustomDataType type; + eCustomDataType type; int states_len; /* number of layers for each type */ BArrayState *states[0]; } BArrayCustomData; @@ -149,7 +149,7 @@ static void um_arraystore_cd_compact(struct CustomData *cdata, const BArrayCustomData *bcd_reference_current = bcd_reference; BArrayCustomData *bcd = NULL, *bcd_first = NULL, *bcd_prev = NULL; for (int layer_start = 0, layer_end; layer_start < cdata->totlayer; layer_start = layer_end) { - const CustomDataType type = cdata->layers[layer_start].type; + const eCustomDataType type = cdata->layers[layer_start].type; /* Perform a full copy on dynamic layers. * diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc index 422aaa03120..5e09948e192 100644 --- a/source/blender/editors/object/object_add.cc +++ b/source/blender/editors/object/object_add.cc @@ -621,9 +621,16 @@ Object *ED_object_add_type_with_obdata(bContext *C, else { ob = BKE_object_add(bmain, view_layer, type, name); } - BASACT(view_layer)->local_view_bits = local_view_bits; - /* editor level activate, notifiers */ - ED_object_base_activate(C, view_layer->basact); + + Base *ob_base_act = BASACT(view_layer); + /* While not getting a valid base is not a good thing, it can happen in convoluted corner cases, + * better not crash on it in releases. */ + BLI_assert(ob_base_act != nullptr); + if (ob_base_act != nullptr) { + ob_base_act->local_view_bits = local_view_bits; + /* editor level activate, notifiers */ + ED_object_base_activate(C, ob_base_act); + } /* more editor stuff */ ED_object_base_init_transform_on_add(ob, loc, rot); diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 1483c24ac70..effbde41c38 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -220,22 +220,22 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); Mesh *me = (Mesh *)ob->data; MultiresModifierData tmp_mmd = *mmd; - DerivedMesh *cddm = CDDM_from_mesh(me); - DM_set_only_copy(cddm, &CD_MASK_BAREMESH); + *lvl = mmd->lvl; if (mmd->lvl == 0) { - dm = CDDM_copy(cddm); - } - else { - tmp_mmd.lvl = mmd->lvl; - tmp_mmd.sculptlvl = mmd->lvl; - dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0); + DerivedMesh *cddm = CDDM_from_mesh(me); + DM_set_only_copy(cddm, &CD_MASK_BAREMESH); + return cddm; } - cddm->release(cddm); + DerivedMesh *cddm = CDDM_from_mesh(me); + DM_set_only_copy(cddm, &CD_MASK_BAREMESH); + tmp_mmd.lvl = mmd->lvl; + tmp_mmd.sculptlvl = mmd->lvl; + dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0); - *lvl = mmd->lvl; + cddm->release(cddm); return dm; } diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 114b2ce8102..006379123f8 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -21,6 +21,7 @@ #include "BLI_path_util.h" #include "BLI_string.h" +#include "BKE_callbacks.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_image.h" @@ -1535,7 +1536,7 @@ static int bake(const BakeAPIRender *bkr, ob_low_eval->obmat); } else { - /* from multiresolution */ + /* From multi-resolution. */ Mesh *me_nores = NULL; ModifierData *md = NULL; int mode; @@ -1806,6 +1807,17 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa RE_SetReports(bkr->render, NULL); } +static void bake_job_complete(void *bkv) +{ + BakeAPIRender *bkr = (BakeAPIRender *)bkv; + BKE_callback_exec_id(bkr->main, &bkr->ob->id, BKE_CB_EVT_OBJECT_BAKE_COMPLETE); +} +static void bake_job_canceled(void *bkv) +{ + BakeAPIRender *bkr = (BakeAPIRender *)bkv; + BKE_callback_exec_id(bkr->main, &bkr->ob->id, BKE_CB_EVT_OBJECT_BAKE_CANCEL); +} + static void bake_freejob(void *bkv) { BakeAPIRender *bkr = (BakeAPIRender *)bkv; @@ -1941,6 +1953,7 @@ static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) /* init bake render */ bake_init_api_data(op, C, bkr); + BKE_callback_exec_id(CTX_data_main(C), &bkr->ob->id, BKE_CB_EVT_OBJECT_BAKE_PRE); re = bkr->render; /* setup new render */ @@ -1958,7 +1971,8 @@ static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) /* TODO: only draw bake image, can we enforce this. */ WM_jobs_timer( wm_job, 0.5, (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) ? NC_GEOM | ND_DATA : NC_IMAGE, 0); - WM_jobs_callbacks(wm_job, bake_startjob, NULL, NULL, NULL); + WM_jobs_callbacks_ex( + wm_job, bake_startjob, NULL, NULL, NULL, bake_job_complete, bake_job_canceled); G.is_break = false; G.is_rendering = true; diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index d982d86fe77..bf3b71178e8 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -245,13 +245,11 @@ static void set_constraint_nth_target(bConstraint *con, const char subtarget[], int index) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; int num_targets, i; - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); + if (BKE_constraint_targets_get(con, &targets)) { num_targets = BLI_listbase_count(&targets); if (index < 0) { @@ -274,9 +272,7 @@ static void set_constraint_nth_target(bConstraint *con, } } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, 0); - } + BKE_constraint_targets_flush(con, &targets, 0); } } @@ -289,7 +285,6 @@ static void set_constraint_nth_target(bConstraint *con, static void test_constraint( Main *bmain, Object *owner, bPoseChannel *pchan, bConstraint *con, int type) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; bool check_targets = true; @@ -465,14 +460,7 @@ static void test_constraint( } /* Check targets for constraints */ - if (check_targets && cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); - - /* constraints with empty target list that actually require targets */ - if (!targets.first && ELEM(con->type, CONSTRAINT_TYPE_ARMATURE)) { - con->flag |= CONSTRAINT_DISABLE; - } - + if (check_targets && BKE_constraint_targets_get(con, &targets)) { /* disable and clear constraints targets that are incorrect */ for (ct = targets.first; ct; ct = ct->next) { /* general validity checks (for those constraints that need this) */ @@ -543,8 +531,12 @@ static void test_constraint( } /* free any temporary targets */ - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, 0); + BKE_constraint_targets_flush(con, &targets, 0); + } + else if (check_targets) { + /* constraints with empty target list that actually require targets */ + if (ELEM(con->type, CONSTRAINT_TYPE_ARMATURE)) { + con->flag |= CONSTRAINT_DISABLE; } } } diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index b9a4c79ac03..4837b538bf6 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -88,14 +88,14 @@ static const EnumPropertyItem DT_layer_items[] = { }; static void dt_add_vcol_layers(CustomData *cdata, - CustomDataMask mask, + eCustomDataMask mask, EnumPropertyItem **r_item, int *r_totitem) { int types[2] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; for (int i = 0; i < 2; i++) { - CustomDataType type = types[i]; + eCustomDataType type = types[i]; if (!(mask & CD_TYPE_AS_MASK(type))) { continue; diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 1067c2d6a95..8a0d380ff2f 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -281,7 +281,7 @@ void ED_operatormacros_object(void) ot = WM_operatortype_append_macro("OBJECT_OT_duplicate_move", "Duplicate Objects", - "Duplicate selected objects and move them", + "Duplicate the selected objects and move them", OPTYPE_UNDO | OPTYPE_REGISTER); if (ot) { WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate"); @@ -289,11 +289,11 @@ void ED_operatormacros_object(void) RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false); } - /* grr, should be able to pass options on... */ - ot = WM_operatortype_append_macro("OBJECT_OT_duplicate_move_linked", - "Duplicate Linked", - "Duplicate selected objects and move them", - OPTYPE_UNDO | OPTYPE_REGISTER); + ot = WM_operatortype_append_macro( + "OBJECT_OT_duplicate_move_linked", + "Duplicate Linked", + "Duplicate the selected objects, but not their object data, and move them", + OPTYPE_UNDO | OPTYPE_REGISTER); if (ot) { otmacro = WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate"); RNA_boolean_set(otmacro->ptr, "linked", true); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 39c664193f1..0a18ad7c50d 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -4269,7 +4269,6 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr) Mesh *me = ob->data; BMEditMesh *em = me->edit_mesh; - float weight_act; int i; if (em) { @@ -4281,18 +4280,15 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr) if (dvert_act == NULL) { return; } - weight_act = BKE_defvert_find_weight(dvert_act, def_nr); BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && (eve != eve_act)) { - MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); - MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr); - if (dw) { - dw->weight = weight_act; + MDeformVert *dvert_dst = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); - if (me->symmetry & ME_SYMMETRY_X) { - ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset); - } + BKE_defvert_copy_index(dvert_dst, def_nr, dvert_act, def_nr); + + if (me->symmetry & ME_SYMMETRY_X) { + ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset); } } } @@ -4309,17 +4305,15 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr) if (dvert_act == NULL) { return; } - weight_act = BKE_defvert_find_weight(dvert_act, def_nr); dv = me->dvert; for (i = 0; i < me->totvert; i++, dv++) { if ((me->mvert[i].flag & SELECT) && (dv != dvert_act)) { - MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr); - if (dw) { - dw->weight = weight_act; - if (me->symmetry & ME_SYMMETRY_X) { - ED_mesh_defvert_mirror_update_ob(ob, -1, i); - } + + BKE_defvert_copy_index(dv, def_nr, dvert_act, def_nr); + + if (me->symmetry & ME_SYMMETRY_X) { + ED_mesh_defvert_mirror_update_ob(ob, -1, i); } } } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 43c19670a41..08c8c863729 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -626,8 +626,8 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) screen_geom_vertices_scale(win, screen); ED_screen_areas_iter (win, screen, area) { - /* set spacetype and region callbacks, calls init() */ - /* sets subwindows for regions, adds handlers */ + /* Set space-type and region callbacks, calls init() */ + /* Sets sub-windows for regions, adds handlers. */ ED_area_init(wm, win, area); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index a922e5aaaee..3022bbbd42c 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1477,7 +1477,7 @@ static int area_close_exec(bContext *C, wmOperator *op) bScreen *screen = CTX_wm_screen(C); ScrArea *area = CTX_wm_area(C); - /* This operator is scriptable, so the area passed could be invalid. */ + /* This operator is script-able, so the area passed could be invalid. */ if (BLI_findindex(&screen->areabase, area) == -1) { BKE_report(op->reports, RPT_ERROR, "Area not found in the active screen"); return OPERATOR_CANCELLED; @@ -2722,7 +2722,7 @@ static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event rmd->region->sizey = rmd->region->winy; } - /* now copy to regionmovedata */ + /* Now copy to region-move-data. */ if (ELEM(rmd->edge, AE_LEFT_TO_TOPRIGHT, AE_RIGHT_TO_TOPLEFT)) { rmd->origval = rmd->region->sizex; } diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index d3bf28798c4..dfd8f8b1bb9 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -33,6 +33,8 @@ set(SRC curves_sculpt_delete.cc curves_sculpt_grow_shrink.cc curves_sculpt_ops.cc + curves_sculpt_selection.cc + curves_sculpt_selection_paint.cc curves_sculpt_snake_hook.cc paint_canvas.cc paint_cursor.c diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc index d7f4b71d2d0..390f142ac0f 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc @@ -85,10 +85,7 @@ static void initialize_straight_curve_positions(const float3 &p1, */ struct AddOperationExecutor { AddOperation *self_ = nullptr; - const Depsgraph *depsgraph_ = nullptr; - const Scene *scene_ = nullptr; - ARegion *region_ = nullptr; - const View3D *v3d_ = nullptr; + CurvesSculptCommonContext ctx_; Object *object_ = nullptr; Curves *curves_id_ = nullptr; @@ -143,14 +140,14 @@ struct AddOperationExecutor { static constexpr int max_neighbors = 5; using NeighborsVector = Vector<NeighborInfo, max_neighbors>; + AddOperationExecutor(const bContext &C) : ctx_(C) + { + } + void execute(AddOperation &self, const bContext &C, const StrokeExtension &stroke_extension) { self_ = &self; - depsgraph_ = CTX_data_depsgraph_pointer(&C); - scene_ = CTX_data_scene(&C); object_ = CTX_data_active_object(&C); - region_ = CTX_wm_region(&C); - v3d_ = CTX_wm_view3d(&C); curves_id_ = static_cast<Curves *>(object_->data); curves_ = &CurvesGeometry::wrap(curves_id_->geometry); @@ -176,10 +173,10 @@ struct AddOperationExecutor { reinterpret_cast<const float3 *>(CustomData_get_layer(&surface_->ldata, CD_NORMAL)), surface_->totloop}; - curves_sculpt_ = scene_->toolsettings->curves_sculpt; + curves_sculpt_ = ctx_.scene->toolsettings->curves_sculpt; brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint); brush_settings_ = brush_->curves_sculpt_settings; - brush_radius_re_ = brush_radius_get(*scene_, *brush_, stroke_extension); + brush_radius_re_ = brush_radius_get(*ctx_.scene, *brush_, stroke_extension); brush_pos_re_ = stroke_extension.mouse_position; use_front_face_ = brush_->flag & BRUSH_FRONTFACE; @@ -256,7 +253,7 @@ struct AddOperationExecutor { DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, &curves_id_->id); - ED_region_tag_redraw(region_); + ED_region_tag_redraw(ctx_.region); } float3 get_bary_coords(const Mesh &mesh, const MLoopTri &looptri, const float3 position) const @@ -276,7 +273,7 @@ struct AddOperationExecutor { { float3 ray_start_wo, ray_end_wo; ED_view3d_win_to_segment_clipped( - depsgraph_, region_, v3d_, brush_pos_re_, ray_start_wo, ray_end_wo, true); + ctx_.depsgraph, ctx_.region, ctx_.v3d, brush_pos_re_, ray_start_wo, ray_end_wo, true); const float3 ray_start_su = world_to_surface_mat_ * ray_start_wo; const float3 ray_end_su = world_to_surface_mat_ * ray_end_wo; @@ -352,7 +349,7 @@ struct AddOperationExecutor { float3 ray_start_wo, ray_end_wo; ED_view3d_win_to_segment_clipped( - depsgraph_, region_, v3d_, pos_re, ray_start_wo, ray_end_wo, true); + ctx_.depsgraph, ctx_.region, ctx_.v3d, pos_re, ray_start_wo, ray_end_wo, true); const float3 ray_start_su = brush_transform * (world_to_surface_mat_ * ray_start_wo); const float3 ray_end_su = brush_transform * (world_to_surface_mat_ * ray_end_wo); const float3 ray_direction_su = math::normalize(ray_end_su - ray_start_su); @@ -400,17 +397,22 @@ struct AddOperationExecutor { { /* Find ray that starts in the center of the brush. */ float3 brush_ray_start_wo, brush_ray_end_wo; - ED_view3d_win_to_segment_clipped( - depsgraph_, region_, v3d_, brush_pos_re_, brush_ray_start_wo, brush_ray_end_wo, true); + ED_view3d_win_to_segment_clipped(ctx_.depsgraph, + ctx_.region, + ctx_.v3d, + brush_pos_re_, + brush_ray_start_wo, + brush_ray_end_wo, + true); const float3 brush_ray_start_su = world_to_surface_mat_ * brush_ray_start_wo; const float3 brush_ray_end_su = world_to_surface_mat_ * brush_ray_end_wo; /* Find ray that starts on the boundary of the brush. That is used to compute the brush radius * in 3D. */ float3 brush_radius_ray_start_wo, brush_radius_ray_end_wo; - ED_view3d_win_to_segment_clipped(depsgraph_, - region_, - v3d_, + ED_view3d_win_to_segment_clipped(ctx_.depsgraph, + ctx_.region, + ctx_.v3d, brush_pos_re_ + float2(brush_radius_re_, 0), brush_radius_ray_start_wo, brush_radius_ray_end_wo, @@ -652,6 +654,8 @@ struct AddOperationExecutor { Array<float3> new_normals_su = this->compute_normals_for_added_curves_su(added_points); this->initialize_surface_attachment(added_points); + this->fill_new_selection(); + if (interpolate_shape_) { this->initialize_position_with_interpolation( added_points, neighbors_per_curve, new_normals_su, new_lengths_cu); @@ -662,6 +666,33 @@ struct AddOperationExecutor { } } + /** + * Select newly created points or curves in new curves if necessary. + */ + void fill_new_selection() + { + switch (curves_id_->selection_domain) { + case ATTR_DOMAIN_CURVE: { + const VArray<float> selection = curves_->selection_curve_float(); + if (selection.is_single() && selection.get_internal_single() >= 1.0f) { + return; + } + curves_->selection_curve_float_for_write().drop_front(tot_old_curves_).fill(1.0f); + break; + } + case ATTR_DOMAIN_POINT: { + const VArray<float> selection = curves_->selection_point_float(); + if (selection.is_single() && selection.get_internal_single() >= 1.0f) { + return; + } + curves_->selection_point_float_for_write().drop_front(tot_old_points_).fill(1.0f); + break; + } + default: + BLI_assert_unreachable(); + } + } + Array<NeighborsVector> find_curve_neighbors(const AddedPoints &added_points) { const int tot_added_curves = added_points.bary_coords.size(); @@ -866,7 +897,7 @@ struct AddOperationExecutor { void AddOperation::on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) { - AddOperationExecutor executor; + AddOperationExecutor executor{C}; executor.execute(*this, C, stroke_extension); } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc index 92ce6ba3153..11d3548a082 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc @@ -13,6 +13,7 @@ #include "UI_interface.h" #include "BLI_enumerable_thread_specific.hh" +#include "BLI_length_parameterize.hh" #include "BLI_task.hh" /** @@ -277,4 +278,44 @@ Vector<float4x4> get_symmetry_brush_transforms(const eCurvesSymmetryType symmetr return matrices; } +void move_last_point_and_resample(MutableSpan<float3> positions, const float3 &new_last_position) +{ + /* Find the accumulated length of each point in the original curve, + * treating it as a poly curve for performance reasons and simplicity. */ + Array<float> orig_lengths(length_parameterize::lengths_num(positions.size(), false)); + length_parameterize::accumulate_lengths<float3>(positions, false, orig_lengths); + const float orig_total_length = orig_lengths.last(); + + /* Find the factor by which the new curve is shorter or longer than the original. */ + const float new_last_segment_length = math::distance(positions.last(1), new_last_position); + const float new_total_length = orig_lengths.last(1) + new_last_segment_length; + const float length_factor = safe_divide(new_total_length, orig_total_length); + + /* Calculate the lengths to sample the original curve with by scaling the original lengths. */ + Array<float> new_lengths(positions.size() - 1); + new_lengths.first() = 0.0f; + for (const int i : new_lengths.index_range().drop_front(1)) { + new_lengths[i] = orig_lengths[i - 1] * length_factor; + } + + Array<int> indices(positions.size() - 1); + Array<float> factors(positions.size() - 1); + length_parameterize::create_samples_from_sorted_lengths( + orig_lengths, new_lengths, false, indices, factors); + + Array<float3> new_positions(positions.size() - 1); + length_parameterize::linear_interpolation<float3>(positions, indices, factors, new_positions); + positions.drop_back(1).copy_from(new_positions); + positions.last() = new_last_position; +} + +CurvesSculptCommonContext::CurvesSculptCommonContext(const bContext &C) +{ + this->depsgraph = CTX_data_depsgraph_pointer(&C); + this->scene = CTX_data_scene(&C); + this->region = CTX_wm_region(&C); + this->v3d = CTX_wm_view3d(&C); + this->rv3d = CTX_wm_region_view3d(&C); +} + } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc index 1fcab2290e8..71f08cce8ff 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc @@ -78,11 +78,7 @@ class CombOperation : public CurvesSculptStrokeOperation { */ struct CombOperationExecutor { CombOperation *self_ = nullptr; - const Depsgraph *depsgraph_ = nullptr; - const Scene *scene_ = nullptr; - ARegion *region_ = nullptr; - const View3D *v3d_ = nullptr; - const RegionView3D *rv3d_ = nullptr; + CurvesSculptCommonContext ctx_; const CurvesSculpt *curves_sculpt_ = nullptr; const Brush *brush_ = nullptr; @@ -96,9 +92,9 @@ struct CombOperationExecutor { Curves *curves_id_ = nullptr; CurvesGeometry *curves_ = nullptr; - const Object *surface_ob_ = nullptr; - const Mesh *surface_ = nullptr; - Span<MLoopTri> surface_looptris_; + VArray<float> point_factors_; + Vector<int64_t> selected_curve_indices_; + IndexMask curve_selection_; float2 brush_pos_prev_re_; float2 brush_pos_re_; @@ -110,7 +106,9 @@ struct CombOperationExecutor { float4x4 surface_to_world_mat_; float4x4 world_to_surface_mat_; - BVHTreeFromMesh surface_bvh_; + CombOperationExecutor(const bContext &C) : ctx_(C) + { + } void execute(CombOperation &self, const bContext &C, const StrokeExtension &stroke_extension) { @@ -118,18 +116,13 @@ struct CombOperationExecutor { BLI_SCOPED_DEFER([&]() { self_->brush_pos_last_re_ = stroke_extension.mouse_position; }); - depsgraph_ = CTX_data_depsgraph_pointer(&C); - scene_ = CTX_data_scene(&C); object_ = CTX_data_active_object(&C); - region_ = CTX_wm_region(&C); - v3d_ = CTX_wm_view3d(&C); - rv3d_ = CTX_wm_region_view3d(&C); - curves_sculpt_ = scene_->toolsettings->curves_sculpt; + curves_sculpt_ = ctx_.scene->toolsettings->curves_sculpt; brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint); - brush_radius_base_re_ = BKE_brush_size_get(scene_, brush_); + brush_radius_base_re_ = BKE_brush_size_get(ctx_.scene, brush_); brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension); - brush_strength_ = brush_strength_get(*scene_, *brush_, stroke_extension); + brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension); curves_to_world_mat_ = object_->obmat; world_to_curves_mat_ = curves_to_world_mat_.inverted(); @@ -142,27 +135,14 @@ struct CombOperationExecutor { return; } + point_factors_ = get_point_selection(*curves_id_); + curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + brush_pos_prev_re_ = self_->brush_pos_last_re_; brush_pos_re_ = stroke_extension.mouse_position; brush_pos_diff_re_ = brush_pos_re_ - brush_pos_prev_re_; brush_pos_diff_length_re_ = math::length(brush_pos_diff_re_); - surface_ob_ = curves_id_->surface; - if (surface_ob_ != nullptr) { - surface_ = static_cast<const Mesh *>(surface_ob_->data); - surface_looptris_ = {BKE_mesh_runtime_looptri_ensure(surface_), - BKE_mesh_runtime_looptri_len(surface_)}; - surface_to_world_mat_ = surface_ob_->obmat; - world_to_surface_mat_ = surface_to_world_mat_.inverted(); - BKE_bvhtree_from_mesh_get(&surface_bvh_, surface_, BVHTREE_FROM_LOOPTRI, 2); - } - - BLI_SCOPED_DEFER([&]() { - if (surface_ob_ != nullptr) { - free_bvhtree_from_mesh(&surface_bvh_); - } - }); - if (stroke_extension.is_first) { if (falloff_shape_ == PAINT_FALLOFF_SHAPE_SPHERE) { this->initialize_spherical_brush_reference_point(); @@ -189,7 +169,7 @@ struct CombOperationExecutor { curves_->tag_positions_changed(); DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, &curves_id_->id); - ED_region_tag_redraw(region_); + ED_region_tag_redraw(ctx_.region); } /** @@ -212,14 +192,14 @@ struct CombOperationExecutor { MutableSpan<float3> positions_cu = curves_->positions_for_write(); float4x4 projection; - ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_; const float brush_radius_sq_re = pow2f(brush_radius_re); - threading::parallel_for(curves_->curves_range(), 256, [&](const IndexRange curves_range) { + threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { Vector<int> &local_changed_curves = r_changed_curves.local(); - for (const int curve_i : curves_range) { + for (const int curve_i : curve_selection_.slice(range)) { bool curve_changed = false; const IndexRange points = curves_->points_for_curve(curve_i); for (const int point_i : points.drop_front(1)) { @@ -227,7 +207,7 @@ struct CombOperationExecutor { /* Find the position of the point in screen space. */ float2 old_pos_re; - ED_view3d_project_float_v2_m4(region_, old_pos_cu, old_pos_re, projection.values); + ED_view3d_project_float_v2_m4(ctx_.region, old_pos_cu, old_pos_re, projection.values); const float distance_to_brush_sq_re = dist_squared_to_line_segment_v2( old_pos_re, brush_pos_prev_re_, brush_pos_re_); @@ -241,13 +221,17 @@ struct CombOperationExecutor { const float radius_falloff = BKE_brush_curve_strength( brush_, distance_to_brush_re, brush_radius_re); /* Combine the falloff and brush strength. */ - const float weight = brush_strength_ * radius_falloff; + const float weight = brush_strength_ * radius_falloff * point_factors_[point_i]; - /* Offset the old point position in screen space and transform it back into 3D space. */ + /* Offset the old point position in screen space and transform it back into 3D space. + */ const float2 new_position_re = old_pos_re + brush_pos_diff_re_ * weight; float3 new_position_wo; - ED_view3d_win_to_3d( - v3d_, region_, curves_to_world_mat_ * old_pos_cu, new_position_re, new_position_wo); + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, + curves_to_world_mat_ * old_pos_cu, + new_position_re, + new_position_wo); const float3 new_position_cu = brush_transform * (world_to_curves_mat_ * new_position_wo); positions_cu[point_i] = new_position_cu; @@ -267,16 +251,16 @@ struct CombOperationExecutor { void comb_spherical_with_symmetry(EnumerableThreadSpecific<Vector<int>> &r_changed_curves) { float4x4 projection; - ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); float3 brush_start_wo, brush_end_wo; - ED_view3d_win_to_3d(v3d_, - region_, + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, curves_to_world_mat_ * self_->brush_3d_.position_cu, brush_pos_prev_re_, brush_start_wo); - ED_view3d_win_to_3d(v3d_, - region_, + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, curves_to_world_mat_ * self_->brush_3d_.position_cu, brush_pos_re_, brush_end_wo); @@ -304,9 +288,9 @@ struct CombOperationExecutor { const float brush_radius_sq_cu = pow2f(brush_radius_cu); const float3 brush_diff_cu = brush_end_cu - brush_start_cu; - threading::parallel_for(curves_->curves_range(), 256, [&](const IndexRange curves_range) { + threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { Vector<int> &local_changed_curves = r_changed_curves.local(); - for (const int curve_i : curves_range) { + for (const int curve_i : curve_selection_.slice(range)) { bool curve_changed = false; const IndexRange points = curves_->points_for_curve(curve_i); for (const int point_i : points.drop_front(1)) { @@ -326,7 +310,7 @@ struct CombOperationExecutor { const float radius_falloff = BKE_brush_curve_strength( brush_, distance_to_brush_cu, brush_radius_cu); /* Combine the falloff and brush strength. */ - const float weight = brush_strength_ * radius_falloff; + const float weight = brush_strength_ * radius_falloff * point_factors_[point_i]; /* Update the point position. */ positions_cu[point_i] = pos_old_cu + weight * brush_diff_cu; @@ -344,8 +328,13 @@ struct CombOperationExecutor { */ void initialize_spherical_brush_reference_point() { - std::optional<CurvesBrush3D> brush_3d = sample_curves_3d_brush( - *depsgraph_, *region_, *v3d_, *rv3d_, *object_, brush_pos_re_, brush_radius_base_re_); + std::optional<CurvesBrush3D> brush_3d = sample_curves_3d_brush(*ctx_.depsgraph, + *ctx_.region, + *ctx_.v3d, + *ctx_.rv3d, + *object_, + brush_pos_re_, + brush_radius_base_re_); if (brush_3d.has_value()) { self_->brush_3d_ = *brush_3d; } @@ -399,7 +388,7 @@ struct CombOperationExecutor { void CombOperation::on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) { - CombOperationExecutor executor; + CombOperationExecutor executor{C}; executor.execute(*this, C, stroke_extension); } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc index 323e99df099..6f12d539aa2 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc @@ -60,16 +60,15 @@ class DeleteOperation : public CurvesSculptStrokeOperation { struct DeleteOperationExecutor { DeleteOperation *self_ = nullptr; - const Depsgraph *depsgraph_ = nullptr; - const Scene *scene_ = nullptr; - ARegion *region_ = nullptr; - const View3D *v3d_ = nullptr; - const RegionView3D *rv3d_ = nullptr; + CurvesSculptCommonContext ctx_; Object *object_ = nullptr; Curves *curves_id_ = nullptr; CurvesGeometry *curves_ = nullptr; + Vector<int64_t> selected_curve_indices_; + IndexMask curve_selection_; + const CurvesSculpt *curves_sculpt_ = nullptr; const Brush *brush_ = nullptr; float brush_radius_base_re_; @@ -80,23 +79,24 @@ struct DeleteOperationExecutor { float4x4 curves_to_world_mat_; float4x4 world_to_curves_mat_; - void execute(DeleteOperation &self, const bContext &C, const StrokeExtension &stroke_extension) + DeleteOperationExecutor(const bContext &C) : ctx_(C) { + } + void execute(DeleteOperation &self, const bContext &C, const StrokeExtension &stroke_extension) + { self_ = &self; - depsgraph_ = CTX_data_depsgraph_pointer(&C); - scene_ = CTX_data_scene(&C); object_ = CTX_data_active_object(&C); - region_ = CTX_wm_region(&C); - v3d_ = CTX_wm_view3d(&C); - rv3d_ = CTX_wm_region_view3d(&C); curves_id_ = static_cast<Curves *>(object_->data); curves_ = &CurvesGeometry::wrap(curves_id_->geometry); - curves_sculpt_ = scene_->toolsettings->curves_sculpt; + selected_curve_indices_.clear(); + curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + + curves_sculpt_ = ctx_.scene->toolsettings->curves_sculpt; brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint); - brush_radius_base_re_ = BKE_brush_size_get(scene_, brush_); + brush_radius_base_re_ = BKE_brush_size_get(ctx_.scene, brush_); brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension); brush_pos_re_ = stroke_extension.mouse_position; @@ -134,7 +134,7 @@ struct DeleteOperationExecutor { DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, &curves_id_->id); - ED_region_tag_redraw(region_); + ED_region_tag_redraw(ctx_.region); } void delete_projected_with_symmetry(MutableSpan<bool> curves_to_delete) @@ -151,20 +151,20 @@ struct DeleteOperationExecutor { const float4x4 brush_transform_inv = brush_transform.inverted(); float4x4 projection; - ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); Span<float3> positions_cu = curves_->positions(); const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_; const float brush_radius_sq_re = pow2f(brush_radius_re); - threading::parallel_for(curves_->curves_range(), 512, [&](IndexRange curve_range) { - for (const int curve_i : curve_range) { + threading::parallel_for(curve_selection_.index_range(), 512, [&](const IndexRange range) { + for (const int curve_i : curve_selection_.slice(range)) { const IndexRange points = curves_->points_for_curve(curve_i); if (points.size() == 1) { const float3 pos_cu = brush_transform_inv * positions_cu[points.first()]; float2 pos_re; - ED_view3d_project_float_v2_m4(region_, pos_cu, pos_re, projection.values); + ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.values); if (math::distance_squared(brush_pos_re_, pos_re) <= brush_radius_sq_re) { curves_to_delete[curve_i] = true; @@ -177,8 +177,8 @@ struct DeleteOperationExecutor { const float3 pos2_cu = brush_transform_inv * positions_cu[segment_i + 1]; float2 pos1_re, pos2_re; - ED_view3d_project_float_v2_m4(region_, pos1_cu, pos1_re, projection.values); - ED_view3d_project_float_v2_m4(region_, pos2_cu, pos2_re, projection.values); + ED_view3d_project_float_v2_m4(ctx_.region, pos1_cu, pos1_re, projection.values); + ED_view3d_project_float_v2_m4(ctx_.region, pos2_cu, pos2_re, projection.values); const float dist_sq_re = dist_squared_to_line_segment_v2( brush_pos_re_, pos1_re, pos2_re); @@ -194,11 +194,11 @@ struct DeleteOperationExecutor { void delete_spherical_with_symmetry(MutableSpan<bool> curves_to_delete) { float4x4 projection; - ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); float3 brush_wo; - ED_view3d_win_to_3d(v3d_, - region_, + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, curves_to_world_mat_ * self_->brush_3d_.position_cu, brush_pos_re_, brush_wo); @@ -219,8 +219,8 @@ struct DeleteOperationExecutor { const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_; const float brush_radius_sq_cu = pow2f(brush_radius_cu); - threading::parallel_for(curves_->curves_range(), 512, [&](IndexRange curve_range) { - for (const int curve_i : curve_range) { + threading::parallel_for(curve_selection_.index_range(), 512, [&](const IndexRange range) { + for (const int curve_i : curve_selection_.slice(range)) { const IndexRange points = curves_->points_for_curve(curve_i); if (points.size() == 1) { @@ -249,8 +249,13 @@ struct DeleteOperationExecutor { void initialize_spherical_brush_reference_point() { - std::optional<CurvesBrush3D> brush_3d = sample_curves_3d_brush( - *depsgraph_, *region_, *v3d_, *rv3d_, *object_, brush_pos_re_, brush_radius_base_re_); + std::optional<CurvesBrush3D> brush_3d = sample_curves_3d_brush(*ctx_.depsgraph, + *ctx_.region, + *ctx_.v3d, + *ctx_.rv3d, + *object_, + brush_pos_re_, + brush_radius_base_re_); if (brush_3d.has_value()) { self_->brush_3d_ = *brush_3d; } @@ -260,7 +265,7 @@ struct DeleteOperationExecutor { void DeleteOperation::on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) { - DeleteOperationExecutor executor; + DeleteOperationExecutor executor{C}; executor.execute(*this, C, stroke_extension); } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc index 25eb8041f4c..3420659520b 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc @@ -151,50 +151,10 @@ class ExtrapolateCurvesEffect : public CurvesEffect { const float3 direction = math::normalize(old_last_pos_cu - direction_reference_point); const float3 new_last_pos_cu = old_last_pos_cu + direction * move_distance_cu; - this->move_last_point_and_resample(positions_cu, curve_points, new_last_pos_cu); + move_last_point_and_resample(positions_cu.slice(curve_points), new_last_pos_cu); } }); } - - void move_last_point_and_resample(MutableSpan<float3> positions, - const IndexRange curve_points, - const float3 &new_last_point_position) const - { - Vector<float> old_lengths; - old_lengths.append(0.0f); - /* Used to (1) normalize the segment sizes over time and (2) support making zero-length - * segments */ - const float extra_length = 0.001f; - for (const int segment_i : IndexRange(curve_points.size() - 1)) { - const float3 &p1 = positions[curve_points[segment_i]]; - const float3 &p2 = positions[curve_points[segment_i] + 1]; - const float length = math::distance(p1, p2); - old_lengths.append(old_lengths.last() + length + extra_length); - } - Vector<float> point_factors; - for (float &old_length : old_lengths) { - point_factors.append(old_length / old_lengths.last()); - } - - PolySpline new_spline; - new_spline.resize(curve_points.size()); - MutableSpan<float3> new_spline_positions = new_spline.positions(); - for (const int i : IndexRange(curve_points.size() - 1)) { - new_spline_positions[i] = positions[curve_points[i]]; - } - new_spline_positions.last() = new_last_point_position; - new_spline.mark_cache_invalid(); - - for (const int i : IndexRange(curve_points.size())) { - const float factor = point_factors[i]; - const Spline::LookupResult lookup = new_spline.lookup_evaluated_factor(factor); - const float index_factor = lookup.evaluated_index + lookup.factor; - float3 p; - new_spline.sample_with_index_factors<float3>( - new_spline_positions, {&index_factor, 1}, {&p, 1}); - positions[curve_points[i]] = p; - } - } }; /** @@ -270,16 +230,16 @@ class CurvesEffectOperation : public CurvesSculptStrokeOperation { */ struct CurvesEffectOperationExecutor { CurvesEffectOperation *self_ = nullptr; - const Depsgraph *depsgraph_ = nullptr; - const Scene *scene_ = nullptr; - ARegion *region_ = nullptr; - const View3D *v3d_ = nullptr; - const RegionView3D *rv3d_ = nullptr; + CurvesSculptCommonContext ctx_; Object *object_ = nullptr; Curves *curves_id_ = nullptr; CurvesGeometry *curves_ = nullptr; + VArray<float> curve_selection_factors_; + Vector<int64_t> selected_curve_indices_; + IndexMask curve_selection_; + const Brush *brush_ = nullptr; float brush_radius_base_re_; float brush_radius_factor_; @@ -298,6 +258,10 @@ struct CurvesEffectOperationExecutor { Vector<float> move_distances_cu; }; + CurvesEffectOperationExecutor(const bContext &C) : ctx_(C) + { + } + void execute(CurvesEffectOperation &self, const bContext &C, const StrokeExtension &stroke_extension) @@ -305,12 +269,7 @@ struct CurvesEffectOperationExecutor { BLI_SCOPED_DEFER([&]() { self.last_mouse_position_ = stroke_extension.mouse_position; }); self_ = &self; - depsgraph_ = CTX_data_depsgraph_pointer(&C); - scene_ = CTX_data_scene(&C); object_ = CTX_data_active_object(&C); - region_ = CTX_wm_region(&C); - v3d_ = CTX_wm_view3d(&C); - rv3d_ = CTX_wm_region_view3d(&C); curves_id_ = static_cast<Curves *>(object_->data); curves_ = &CurvesGeometry::wrap(curves_id_->geometry); @@ -318,13 +277,16 @@ struct CurvesEffectOperationExecutor { return; } - const CurvesSculpt &curves_sculpt = *scene_->toolsettings->curves_sculpt; + curve_selection_factors_ = get_curves_selection(*curves_id_); + curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + + const CurvesSculpt &curves_sculpt = *ctx_.scene->toolsettings->curves_sculpt; brush_ = BKE_paint_brush_for_read(&curves_sculpt.paint); - brush_strength_ = brush_strength_get(*scene_, *brush_, stroke_extension); + brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension); - brush_radius_base_re_ = BKE_brush_size_get(scene_, brush_); + brush_radius_base_re_ = BKE_brush_size_get(ctx_.scene, brush_); brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension); - brush_strength_ = brush_strength_get(*scene_, *brush_, stroke_extension); + brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension); falloff_shape_ = eBrushFalloffShape(brush_->falloff_shape); @@ -337,10 +299,10 @@ struct CurvesEffectOperationExecutor { if (stroke_extension.is_first) { if (falloff_shape_ == PAINT_FALLOFF_SHAPE_SPHERE) { if (std::optional<CurvesBrush3D> brush_3d = sample_curves_3d_brush( - *depsgraph_, - *region_, - *v3d_, - *rv3d_, + *ctx_.depsgraph, + *ctx_.region, + *ctx_.v3d, + *ctx_.rv3d, *object_, stroke_extension.mouse_position, brush_radius_base_re_)) { @@ -369,7 +331,7 @@ struct CurvesEffectOperationExecutor { curves_->tag_positions_changed(); DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, &curves_id_->id); - ED_region_tag_redraw(region_); + ED_region_tag_redraw(ctx_.region); } void gather_influences_projected( @@ -378,7 +340,7 @@ struct CurvesEffectOperationExecutor { const Span<float3> positions_cu = curves_->positions(); float4x4 projection; - ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms( eCurvesSymmetryType(curves_id_->symmetry)); @@ -396,6 +358,8 @@ struct CurvesEffectOperationExecutor { for (const int curve_i : curves_range) { const IndexRange points = curves_->points_for_curve(curve_i); + const float curve_selection_factor = curve_selection_factors_[curve_i]; + float max_move_distance_cu = 0.0f; for (const float4x4 &brush_transform_inv : symmetry_brush_transforms_inv) { for (const int segment_i : points.drop_back(1)) { @@ -403,8 +367,8 @@ struct CurvesEffectOperationExecutor { const float3 p2_cu = brush_transform_inv * positions_cu[segment_i + 1]; float2 p1_re, p2_re; - ED_view3d_project_float_v2_m4(region_, p1_cu, p1_re, projection.values); - ED_view3d_project_float_v2_m4(region_, p2_cu, p2_re, projection.values); + ED_view3d_project_float_v2_m4(ctx_.region, p1_cu, p1_re, projection.values); + ED_view3d_project_float_v2_m4(ctx_.region, p2_cu, p2_re, projection.values); float2 closest_on_brush_re; float2 closest_on_segment_re; @@ -426,19 +390,19 @@ struct CurvesEffectOperationExecutor { const float dist_to_brush_re = std::sqrt(dist_to_brush_sq_re); const float radius_falloff = BKE_brush_curve_strength( brush_, dist_to_brush_re, brush_radius_re); - const float weight = brush_strength_ * radius_falloff; + const float weight = brush_strength_ * radius_falloff * curve_selection_factor; const float3 closest_on_segment_cu = math::interpolate( p1_cu, p2_cu, lambda_on_segment); float3 brush_start_pos_wo, brush_end_pos_wo; - ED_view3d_win_to_3d(v3d_, - region_, + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, curves_to_world_mat_ * closest_on_segment_cu, brush_pos_start_re_, brush_start_pos_wo); - ED_view3d_win_to_3d(v3d_, - region_, + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, curves_to_world_mat_ * closest_on_segment_cu, brush_pos_end_re_, brush_end_pos_wo); @@ -464,13 +428,13 @@ struct CurvesEffectOperationExecutor { const Span<float3> positions_cu = curves_->positions(); float3 brush_pos_start_wo, brush_pos_end_wo; - ED_view3d_win_to_3d(v3d_, - region_, + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, curves_to_world_mat_ * self_->brush_3d_.position_cu, brush_pos_start_re_, brush_pos_start_wo); - ED_view3d_win_to_3d(v3d_, - region_, + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, curves_to_world_mat_ * self_->brush_3d_.position_cu, brush_pos_end_re_, brush_pos_end_wo); @@ -491,6 +455,9 @@ struct CurvesEffectOperationExecutor { const IndexRange points = curves_->points_for_curve(curve_i); float max_move_distance_cu = 0.0f; + + const float curve_selection_factor = curve_selection_factors_[curve_i]; + for (const float4x4 &brush_transform : symmetry_brush_transforms) { const float3 brush_pos_start_transformed_cu = brush_transform * brush_pos_start_cu; const float3 brush_pos_end_transformed_cu = brush_transform * brush_pos_end_cu; @@ -517,7 +484,7 @@ struct CurvesEffectOperationExecutor { const float dist_to_brush_cu = std::sqrt(dist_to_brush_sq_cu); const float radius_falloff = BKE_brush_curve_strength( brush_, dist_to_brush_cu, brush_radius_cu); - const float weight = brush_strength_ * radius_falloff; + const float weight = brush_strength_ * radius_falloff * curve_selection_factor; const float move_distance_cu = weight * brush_pos_diff_length_cu; max_move_distance_cu = std::max(max_move_distance_cu, move_distance_cu); @@ -535,7 +502,7 @@ struct CurvesEffectOperationExecutor { void CurvesEffectOperation::on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) { - CurvesEffectOperationExecutor executor; + CurvesEffectOperationExecutor executor{C}; executor.execute(*this, C, stroke_extension); } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh index 842de234761..4aaf6671cdb 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh @@ -8,7 +8,10 @@ #include "paint_intern.h" #include "BLI_math_vector.hh" +#include "BLI_vector.hh" +#include "BLI_virtual_array.hh" +#include "BKE_attribute.h" #include "BKE_curves.hh" struct ARegion; @@ -55,6 +58,8 @@ std::unique_ptr<CurvesSculptStrokeOperation> new_delete_operation(); std::unique_ptr<CurvesSculptStrokeOperation> new_snake_hook_operation(); std::unique_ptr<CurvesSculptStrokeOperation> new_grow_shrink_operation( const BrushStrokeMode brush_mode, const bContext &C); +std::unique_ptr<CurvesSculptStrokeOperation> new_selection_paint_operation( + const BrushStrokeMode brush_mode, const bContext &C); struct CurvesBrush3D { float3 position_cu; @@ -74,4 +79,33 @@ std::optional<CurvesBrush3D> sample_curves_3d_brush(const Depsgraph &depsgraph, Vector<float4x4> get_symmetry_brush_transforms(eCurvesSymmetryType symmetry); +/** + * Get the floating point selection on the curve domain, averaged from points if necessary. + */ +VArray<float> get_curves_selection(const Curves &curves_id); + +/** + * Get the floating point selection on the curve domain, copied from curves if necessary. + */ +VArray<float> get_point_selection(const Curves &curves_id); + +/** + * Find curves that have any point selected (a selection factor greater than zero), + * or curves that have their own selection factor greater than zero. + */ +IndexMask retrieve_selected_curves(const Curves &curves_id, Vector<int64_t> &r_indices); + +void move_last_point_and_resample(MutableSpan<float3> positions, const float3 &new_last_position); + +class CurvesSculptCommonContext { + public: + const Depsgraph *depsgraph = nullptr; + const Scene *scene = nullptr; + ARegion *region = nullptr; + const View3D *v3d = nullptr; + const RegionView3D *rv3d = nullptr; + + CurvesSculptCommonContext(const bContext &C); +}; + } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index 15d0f73592d..dc3dacf9c81 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -49,7 +49,7 @@ bool CURVES_SCULPT_mode_poll(bContext *C) { - Object *ob = CTX_data_active_object(C); + const Object *ob = CTX_data_active_object(C); return ob && ob->mode & OB_MODE_SCULPT_CURVES; } @@ -109,9 +109,9 @@ static std::unique_ptr<CurvesSculptStrokeOperation> start_brush_operation(bConte { const BrushStrokeMode mode = static_cast<BrushStrokeMode>(RNA_enum_get(op.ptr, "mode")); - Scene &scene = *CTX_data_scene(&C); - CurvesSculpt &curves_sculpt = *scene.toolsettings->curves_sculpt; - Brush &brush = *BKE_paint_brush(&curves_sculpt.paint); + const Scene &scene = *CTX_data_scene(&C); + const CurvesSculpt &curves_sculpt = *scene.toolsettings->curves_sculpt; + const Brush &brush = *BKE_paint_brush_for_read(&curves_sculpt.paint); switch (brush.curves_sculpt_tool) { case CURVES_SCULPT_TOOL_COMB: return new_comb_operation(); @@ -123,6 +123,8 @@ static std::unique_ptr<CurvesSculptStrokeOperation> start_brush_operation(bConte return new_add_operation(C, op.reports); case CURVES_SCULPT_TOOL_GROW_SHRINK: return new_grow_shrink_operation(mode, C); + case CURVES_SCULPT_TOOL_SELECTION_PAINT: + return new_selection_paint_operation(mode, C); } BLI_assert_unreachable(); return {}; @@ -180,8 +182,8 @@ static void stroke_done(const bContext *C, PaintStroke *stroke) static int sculpt_curves_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - Paint *paint = BKE_paint_get_active_from_context(C); - Brush *brush = BKE_paint_brush(paint); + const Paint *paint = BKE_paint_get_active_from_context(C); + const Brush *brush = BKE_paint_brush_for_read(paint); if (brush == nullptr) { return OPERATOR_CANCELLED; } @@ -250,7 +252,7 @@ static void SCULPT_CURVES_OT_brush_stroke(struct wmOperatorType *ot) static bool curves_sculptmode_toggle_poll(bContext *C) { - Object *ob = CTX_data_active_object(C); + const Object *ob = CTX_data_active_object(C); if (ob == nullptr) { return false; } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc new file mode 100644 index 00000000000..f620fed5761 --- /dev/null +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BLI_index_mask_ops.hh" + +#include "BKE_curves.hh" + +#include "curves_sculpt_intern.hh" + +namespace blender::ed::sculpt_paint { + +static VArray<float> get_curves_selection(const CurvesGeometry &curves, const eAttrDomain domain) +{ + switch (domain) { + case ATTR_DOMAIN_CURVE: + return curves.selection_curve_float(); + case ATTR_DOMAIN_POINT: + return curves.adapt_domain( + curves.selection_point_float(), ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE); + default: + BLI_assert_unreachable(); + return {}; + } +} + +VArray<float> get_curves_selection(const Curves &curves_id) +{ + if (!(curves_id.flag & CV_SCULPT_SELECTION_ENABLED)) { + return VArray<float>::ForSingle(1.0f, CurvesGeometry::wrap(curves_id.geometry).curves_num()); + } + return get_curves_selection(CurvesGeometry::wrap(curves_id.geometry), + eAttrDomain(curves_id.selection_domain)); +} + +static VArray<float> get_point_selection(const CurvesGeometry &curves, const eAttrDomain domain) +{ + switch (domain) { + case ATTR_DOMAIN_CURVE: + return curves.adapt_domain( + curves.selection_curve_float(), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); + case ATTR_DOMAIN_POINT: + return curves.selection_point_float(); + default: + BLI_assert_unreachable(); + return {}; + } +} + +VArray<float> get_point_selection(const Curves &curves_id) +{ + if (!(curves_id.flag & CV_SCULPT_SELECTION_ENABLED)) { + return VArray<float>::ForSingle(1.0f, CurvesGeometry::wrap(curves_id.geometry).points_num()); + } + return get_point_selection(CurvesGeometry::wrap(curves_id.geometry), + eAttrDomain(curves_id.selection_domain)); +} + +static IndexMask retrieve_selected_curves(const CurvesGeometry &curves, + const eAttrDomain domain, + Vector<int64_t> &r_indices) +{ + switch (domain) { + case ATTR_DOMAIN_POINT: { + const VArray<float> selection = curves.selection_point_float(); + if (selection.is_single()) { + return selection.get_internal_single() == 0.0f ? IndexMask(0) : + IndexMask(curves.curves_num()); + } + return index_mask_ops::find_indices_based_on_predicate( + curves.curves_range(), 512, r_indices, [&](const int curve_i) { + for (const int i : curves.points_for_curve(curve_i)) { + if (selection[i] > 0.0f) { + return true; + } + } + return false; + }); + } + case ATTR_DOMAIN_CURVE: { + const VArray<float> selection = curves.selection_curve_float(); + if (selection.is_single()) { + return selection.get_internal_single() == 0.0f ? IndexMask(0) : + IndexMask(curves.curves_num()); + } + return index_mask_ops::find_indices_based_on_predicate( + curves.curves_range(), 2048, r_indices, [&](const int i) { + return selection[i] > 0.0f; + }); + } + default: + BLI_assert_unreachable(); + return {}; + } +} + +IndexMask retrieve_selected_curves(const Curves &curves_id, Vector<int64_t> &r_indices) +{ + if (!(curves_id.flag & CV_SCULPT_SELECTION_ENABLED)) { + return CurvesGeometry::wrap(curves_id.geometry).curves_range(); + } + return retrieve_selected_curves(CurvesGeometry::wrap(curves_id.geometry), + eAttrDomain(curves_id.selection_domain), + r_indices); +} + +} // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc new file mode 100644 index 00000000000..30793c45bd0 --- /dev/null +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc @@ -0,0 +1,393 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <algorithm> +#include <numeric> + +#include "BLI_memory_utils.hh" +#include "BLI_task.hh" + +#include "DNA_brush_types.h" + +#include "BKE_brush.h" +#include "BKE_context.h" +#include "BKE_curves.hh" + +#include "DEG_depsgraph.h" + +#include "ED_screen.h" +#include "ED_view3d.h" + +#include "WM_api.h" + +#include "curves_sculpt_intern.hh" + +/** + * The code below uses a suffix naming convention to indicate the coordinate space: + * cu: Local space of the curves object that is being edited. + * wo: World space. + * re: 2D coordinates within the region. + */ + +namespace blender::ed::sculpt_paint { + +using bke::CurvesGeometry; + +class SelectionPaintOperation : public CurvesSculptStrokeOperation { + private: + bool use_select_; + bool clear_selection_; + + CurvesBrush3D brush_3d_; + + friend struct SelectionPaintOperationExecutor; + + public: + SelectionPaintOperation(const bool use_select, const bool clear_selection) + : use_select_(use_select), clear_selection_(clear_selection) + { + } + void on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) override; +}; + +struct SelectionPaintOperationExecutor { + SelectionPaintOperation *self_ = nullptr; + CurvesSculptCommonContext ctx_; + + Object *object_ = nullptr; + Curves *curves_id_ = nullptr; + CurvesGeometry *curves_ = nullptr; + + const Brush *brush_ = nullptr; + float brush_radius_base_re_; + float brush_radius_factor_; + float brush_strength_; + + float selection_goal_; + + float2 brush_pos_re_; + + float4x4 curves_to_world_mat_; + float4x4 world_to_curves_mat_; + + SelectionPaintOperationExecutor(const bContext &C) : ctx_(C) + { + } + + void execute(SelectionPaintOperation &self, + const bContext &C, + const StrokeExtension &stroke_extension) + { + self_ = &self; + object_ = CTX_data_active_object(&C); + + curves_id_ = static_cast<Curves *>(object_->data); + curves_ = &CurvesGeometry::wrap(curves_id_->geometry); + curves_id_->flag |= CV_SCULPT_SELECTION_ENABLED; + + brush_ = BKE_paint_brush_for_read(&ctx_.scene->toolsettings->curves_sculpt->paint); + brush_radius_base_re_ = BKE_brush_size_get(ctx_.scene, brush_); + brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension); + brush_strength_ = BKE_brush_alpha_get(ctx_.scene, brush_); + + brush_pos_re_ = stroke_extension.mouse_position; + + if (self.clear_selection_) { + if (stroke_extension.is_first) { + if (curves_id_->selection_domain == ATTR_DOMAIN_POINT) { + curves_->selection_point_float_for_write().fill(0.0f); + } + else if (curves_id_->selection_domain == ATTR_DOMAIN_CURVE) { + curves_->selection_curve_float_for_write().fill(0.0f); + } + } + } + + curves_to_world_mat_ = object_->obmat; + world_to_curves_mat_ = curves_to_world_mat_.inverted(); + + const eBrushFalloffShape falloff_shape = static_cast<eBrushFalloffShape>( + brush_->falloff_shape); + + selection_goal_ = self_->use_select_ ? 1.0f : 0.0f; + + if (stroke_extension.is_first) { + if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + this->initialize_spherical_brush_reference_point(); + } + } + + if (curves_id_->selection_domain == ATTR_DOMAIN_POINT) { + MutableSpan<float> selection = curves_->selection_point_float_for_write(); + if (falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { + this->paint_point_selection_projected_with_symmetry(selection); + } + else if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + this->paint_point_selection_spherical_with_symmetry(selection); + } + } + else { + MutableSpan<float> selection = curves_->selection_curve_float_for_write(); + if (falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { + this->paint_curve_selection_projected_with_symmetry(selection); + } + else if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + this->paint_curve_selection_spherical_with_symmetry(selection); + } + } + + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because + * selection is handled as a generic attribute for now. */ + DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY); + WM_main_add_notifier(NC_GEOM | ND_DATA, &curves_id_->id); + ED_region_tag_redraw(ctx_.region); + } + + void paint_point_selection_projected_with_symmetry(MutableSpan<float> selection) + { + const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms( + eCurvesSymmetryType(curves_id_->symmetry)); + for (const float4x4 &brush_transform : symmetry_brush_transforms) { + this->paint_point_selection_projected(brush_transform, selection); + } + } + + void paint_point_selection_projected(const float4x4 &brush_transform, + MutableSpan<float> selection) + { + const float4x4 brush_transform_inv = brush_transform.inverted(); + + float4x4 projection; + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); + + Span<float3> positions_cu = curves_->positions(); + + const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_; + const float brush_radius_sq_re = pow2f(brush_radius_re); + + threading::parallel_for(curves_->points_range(), 1024, [&](const IndexRange point_range) { + for (const int point_i : point_range) { + const float3 pos_cu = brush_transform_inv * positions_cu[point_i]; + + /* Find the position of the point in screen space. */ + float2 pos_re; + ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.values); + + const float distance_to_brush_sq_re = math::distance_squared(pos_re, brush_pos_re_); + if (distance_to_brush_sq_re > brush_radius_sq_re) { + /* Ignore the point because it's too far away. */ + continue; + } + + const float distance_to_brush_re = std::sqrt(distance_to_brush_sq_re); + /* A falloff that is based on how far away the point is from the stroke. */ + const float radius_falloff = BKE_brush_curve_strength( + brush_, distance_to_brush_re, brush_radius_re); + /* Combine the falloff and brush strength. */ + const float weight = brush_strength_ * radius_falloff; + + selection[point_i] = math::interpolate(selection[point_i], selection_goal_, weight); + } + }); + } + + void paint_point_selection_spherical_with_symmetry(MutableSpan<float> selection) + { + float4x4 projection; + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); + + float3 brush_wo; + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, + curves_to_world_mat_ * self_->brush_3d_.position_cu, + brush_pos_re_, + brush_wo); + const float3 brush_cu = world_to_curves_mat_ * brush_wo; + + const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms( + eCurvesSymmetryType(curves_id_->symmetry)); + + for (const float4x4 &brush_transform : symmetry_brush_transforms) { + this->paint_point_selection_spherical(selection, brush_transform * brush_cu); + } + } + + void paint_point_selection_spherical(MutableSpan<float> selection, const float3 &brush_cu) + { + Span<float3> positions_cu = curves_->positions(); + + const float brush_radius_cu = self_->brush_3d_.radius_cu; + const float brush_radius_sq_cu = pow2f(brush_radius_cu); + + threading::parallel_for(curves_->points_range(), 1024, [&](const IndexRange point_range) { + for (const int i : point_range) { + const float3 pos_old_cu = positions_cu[i]; + + /* Compute distance to the brush. */ + const float distance_to_brush_sq_cu = math::distance_squared(pos_old_cu, brush_cu); + if (distance_to_brush_sq_cu > brush_radius_sq_cu) { + /* Ignore the point because it's too far away. */ + continue; + } + + const float distance_to_brush_cu = std::sqrt(distance_to_brush_sq_cu); + + /* A falloff that is based on how far away the point is from the stroke. */ + const float radius_falloff = BKE_brush_curve_strength( + brush_, distance_to_brush_cu, brush_radius_cu); + /* Combine the falloff and brush strength. */ + const float weight = brush_strength_ * radius_falloff; + + selection[i] = math::interpolate(selection[i], selection_goal_, weight); + } + }); + } + + void paint_curve_selection_projected_with_symmetry(MutableSpan<float> selection) + { + const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms( + eCurvesSymmetryType(curves_id_->symmetry)); + for (const float4x4 &brush_transform : symmetry_brush_transforms) { + this->paint_curve_selection_projected(brush_transform, selection); + } + } + + void paint_curve_selection_projected(const float4x4 &brush_transform, + MutableSpan<float> selection) + { + const Span<float3> positions_cu = curves_->positions(); + const float4x4 brush_transform_inv = brush_transform.inverted(); + + float4x4 projection; + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); + + const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_; + const float brush_radius_sq_re = pow2f(brush_radius_re); + + threading::parallel_for(curves_->curves_range(), 1024, [&](const IndexRange curves_range) { + for (const int curve_i : curves_range) { + const float max_weight = threading::parallel_reduce( + curves_->points_for_curve(curve_i).drop_back(1), + 1024, + 0.0f, + [&](const IndexRange segment_range, const float init) { + float max_weight = init; + for (const int segment_i : segment_range) { + const float3 pos1_cu = brush_transform_inv * positions_cu[segment_i]; + const float3 pos2_cu = brush_transform_inv * positions_cu[segment_i + 1]; + + float2 pos1_re; + float2 pos2_re; + ED_view3d_project_float_v2_m4(ctx_.region, pos1_cu, pos1_re, projection.values); + ED_view3d_project_float_v2_m4(ctx_.region, pos2_cu, pos2_re, projection.values); + + const float distance_sq_re = dist_squared_to_line_segment_v2( + brush_pos_re_, pos1_re, pos2_re); + if (distance_sq_re > brush_radius_sq_re) { + continue; + } + const float radius_falloff = BKE_brush_curve_strength( + brush_, std::sqrt(distance_sq_re), brush_radius_re); + const float weight = brush_strength_ * radius_falloff; + max_weight = std::max(max_weight, weight); + } + return max_weight; + }, + [](float a, float b) { return std::max(a, b); }); + selection[curve_i] = math::interpolate(selection[curve_i], selection_goal_, max_weight); + } + }); + } + + void paint_curve_selection_spherical_with_symmetry(MutableSpan<float> selection) + { + float4x4 projection; + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); + + float3 brush_wo; + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, + curves_to_world_mat_ * self_->brush_3d_.position_cu, + brush_pos_re_, + brush_wo); + const float3 brush_cu = world_to_curves_mat_ * brush_wo; + + const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms( + eCurvesSymmetryType(curves_id_->symmetry)); + + for (const float4x4 &brush_transform : symmetry_brush_transforms) { + this->paint_curve_selection_spherical(selection, brush_transform * brush_cu); + } + } + + void paint_curve_selection_spherical(MutableSpan<float> selection, const float3 &brush_cu) + { + const Span<float3> positions_cu = curves_->positions(); + + const float brush_radius_cu = self_->brush_3d_.radius_cu; + const float brush_radius_sq_cu = pow2f(brush_radius_cu); + + threading::parallel_for(curves_->curves_range(), 1024, [&](const IndexRange curves_range) { + for (const int curve_i : curves_range) { + const float max_weight = threading::parallel_reduce( + curves_->points_for_curve(curve_i).drop_back(1), + 1024, + 0.0f, + [&](const IndexRange segment_range, const float init) { + float max_weight = init; + for (const int segment_i : segment_range) { + const float3 &pos1_cu = positions_cu[segment_i]; + const float3 &pos2_cu = positions_cu[segment_i + 1]; + + const float distance_sq_cu = dist_squared_to_line_segment_v3( + brush_cu, pos1_cu, pos2_cu); + if (distance_sq_cu > brush_radius_sq_cu) { + continue; + } + const float radius_falloff = BKE_brush_curve_strength( + brush_, std::sqrt(distance_sq_cu), brush_radius_cu); + const float weight = brush_strength_ * radius_falloff; + max_weight = std::max(max_weight, weight); + } + return max_weight; + }, + [](float a, float b) { return std::max(a, b); }); + selection[curve_i] = math::interpolate(selection[curve_i], selection_goal_, max_weight); + } + }); + } + + void initialize_spherical_brush_reference_point() + { + std::optional<CurvesBrush3D> brush_3d = sample_curves_3d_brush(*ctx_.depsgraph, + *ctx_.region, + *ctx_.v3d, + *ctx_.rv3d, + *object_, + brush_pos_re_, + brush_radius_base_re_); + if (brush_3d.has_value()) { + self_->brush_3d_ = *brush_3d; + } + } +}; + +void SelectionPaintOperation::on_stroke_extended(const bContext &C, + const StrokeExtension &stroke_extension) +{ + SelectionPaintOperationExecutor executor{C}; + executor.execute(*this, C, stroke_extension); +} + +std::unique_ptr<CurvesSculptStrokeOperation> new_selection_paint_operation( + const BrushStrokeMode brush_mode, const bContext &C) +{ + Scene &scene = *CTX_data_scene(&C); + Brush &brush = *BKE_paint_brush(&scene.toolsettings->curves_sculpt->paint); + const bool use_select = ELEM(brush_mode, BRUSH_STROKE_INVERT) == + ((brush.flag & BRUSH_DIR_IN) != 0); + const bool clear_selection = use_select && brush_mode != BRUSH_STROKE_SMOOTH; + + return std::make_unique<SelectionPaintOperation>(use_select, clear_selection); +} + +} // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc index bcdeaaeabf2..166ef133c68 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc @@ -72,11 +72,7 @@ class SnakeHookOperation : public CurvesSculptStrokeOperation { */ struct SnakeHookOperatorExecutor { SnakeHookOperation *self_ = nullptr; - const Depsgraph *depsgraph_ = nullptr; - const Scene *scene_ = nullptr; - ARegion *region_ = nullptr; - const View3D *v3d_ = nullptr; - const RegionView3D *rv3d_ = nullptr; + CurvesSculptCommonContext ctx_; const CurvesSculpt *curves_sculpt_ = nullptr; const Brush *brush_ = nullptr; @@ -90,6 +86,10 @@ struct SnakeHookOperatorExecutor { Curves *curves_id_ = nullptr; CurvesGeometry *curves_ = nullptr; + VArray<float> curve_factors_; + Vector<int64_t> selected_curve_indices_; + IndexMask curve_selection_; + float4x4 curves_to_world_mat_; float4x4 world_to_curves_mat_; @@ -97,6 +97,10 @@ struct SnakeHookOperatorExecutor { float2 brush_pos_re_; float2 brush_pos_diff_re_; + SnakeHookOperatorExecutor(const bContext &C) : ctx_(C) + { + } + void execute(SnakeHookOperation &self, const bContext &C, const StrokeExtension &stroke_extension) @@ -104,20 +108,14 @@ struct SnakeHookOperatorExecutor { BLI_SCOPED_DEFER([&]() { self.last_mouse_position_re_ = stroke_extension.mouse_position; }); self_ = &self; - depsgraph_ = CTX_data_depsgraph_pointer(&C); - scene_ = CTX_data_scene(&C); - scene_ = CTX_data_scene(&C); object_ = CTX_data_active_object(&C); - region_ = CTX_wm_region(&C); - v3d_ = CTX_wm_view3d(&C); - rv3d_ = CTX_wm_region_view3d(&C); - curves_sculpt_ = scene_->toolsettings->curves_sculpt; + curves_sculpt_ = ctx_.scene->toolsettings->curves_sculpt; brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint); - brush_radius_base_re_ = BKE_brush_size_get(scene_, brush_); + brush_radius_base_re_ = BKE_brush_size_get(ctx_.scene, brush_); brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension); - brush_strength_ = brush_strength_get(*scene_, *brush_, stroke_extension); + brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension); falloff_shape_ = static_cast<eBrushFalloffShape>(brush_->falloff_shape); @@ -130,14 +128,22 @@ struct SnakeHookOperatorExecutor { return; } + curve_factors_ = get_curves_selection(*curves_id_); + curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + brush_pos_prev_re_ = self.last_mouse_position_re_; brush_pos_re_ = stroke_extension.mouse_position; brush_pos_diff_re_ = brush_pos_re_ - brush_pos_prev_re_; if (stroke_extension.is_first) { if (falloff_shape_ == PAINT_FALLOFF_SHAPE_SPHERE) { - std::optional<CurvesBrush3D> brush_3d = sample_curves_3d_brush( - *depsgraph_, *region_, *v3d_, *rv3d_, *object_, brush_pos_re_, brush_radius_base_re_); + std::optional<CurvesBrush3D> brush_3d = sample_curves_3d_brush(*ctx_.depsgraph, + *ctx_.region, + *ctx_.v3d, + *ctx_.rv3d, + *object_, + brush_pos_re_, + brush_radius_base_re_); if (brush_3d.has_value()) { self_->brush_3d_ = *brush_3d; } @@ -158,7 +164,7 @@ struct SnakeHookOperatorExecutor { curves_->tag_positions_changed(); DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, &curves_id_->id); - ED_region_tag_redraw(region_); + ED_region_tag_redraw(ctx_.region); } void projected_snake_hook_with_symmetry() @@ -177,7 +183,7 @@ struct SnakeHookOperatorExecutor { MutableSpan<float3> positions_cu = curves_->positions_for_write(); float4x4 projection; - ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_; const float brush_radius_sq_re = pow2f(brush_radius_re); @@ -189,7 +195,7 @@ struct SnakeHookOperatorExecutor { const float3 old_pos_cu = brush_transform_inv * positions_cu[last_point_i]; float2 old_pos_re; - ED_view3d_project_float_v2_m4(region_, old_pos_cu, old_pos_re, projection.values); + ED_view3d_project_float_v2_m4(ctx_.region, old_pos_cu, old_pos_re, projection.values); const float distance_to_brush_sq_re = math::distance_squared(old_pos_re, brush_pos_prev_re_); @@ -199,15 +205,18 @@ struct SnakeHookOperatorExecutor { const float radius_falloff = BKE_brush_curve_strength( brush_, std::sqrt(distance_to_brush_sq_re), brush_radius_re); - const float weight = brush_strength_ * radius_falloff; + const float weight = brush_strength_ * radius_falloff * curve_factors_[curve_i]; const float2 new_position_re = old_pos_re + brush_pos_diff_re_ * weight; float3 new_position_wo; - ED_view3d_win_to_3d( - v3d_, region_, curves_to_world_mat_ * old_pos_cu, new_position_re, new_position_wo); + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, + curves_to_world_mat_ * old_pos_cu, + new_position_re, + new_position_wo); const float3 new_position_cu = brush_transform * (world_to_curves_mat_ * new_position_wo); - this->move_last_point_and_resample(positions_cu.slice(points), new_position_cu); + move_last_point_and_resample(positions_cu.slice(points), new_position_cu); } }); } @@ -215,16 +224,16 @@ struct SnakeHookOperatorExecutor { void spherical_snake_hook_with_symmetry() { float4x4 projection; - ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); float3 brush_start_wo, brush_end_wo; - ED_view3d_win_to_3d(v3d_, - region_, + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, curves_to_world_mat_ * self_->brush_3d_.position_cu, brush_pos_prev_re_, brush_start_wo); - ED_view3d_win_to_3d(v3d_, - region_, + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, curves_to_world_mat_ * self_->brush_3d_.position_cu, brush_pos_re_, brush_end_wo); @@ -265,52 +274,20 @@ struct SnakeHookOperatorExecutor { const float radius_falloff = BKE_brush_curve_strength( brush_, distance_to_brush_cu, brush_radius_cu); - const float weight = brush_strength_ * radius_falloff; + const float weight = brush_strength_ * radius_falloff * curve_factors_[curve_i]; const float3 new_pos_cu = old_pos_cu + weight * brush_diff_cu; - this->move_last_point_and_resample(positions_cu.slice(points), new_pos_cu); + move_last_point_and_resample(positions_cu.slice(points), new_pos_cu); } }); } - - void move_last_point_and_resample(MutableSpan<float3> positions, - const float3 &new_last_position) const - { - /* Find the accumulated length of each point in the original curve, - * treating it as a poly curve for performance reasons and simplicity. */ - Array<float> orig_lengths(length_parameterize::lengths_num(positions.size(), false)); - length_parameterize::accumulate_lengths<float3>(positions, false, orig_lengths); - const float orig_total_length = orig_lengths.last(); - - /* Find the factor by which the new curve is shorter or longer than the original. */ - const float new_last_segment_length = math::distance(positions.last(1), new_last_position); - const float new_total_length = orig_lengths.last(1) + new_last_segment_length; - const float length_factor = new_total_length / orig_total_length; - - /* Calculate the lengths to sample the original curve with by scaling the original lengths. */ - Array<float> new_lengths(positions.size() - 1); - new_lengths.first() = 0.0f; - for (const int i : new_lengths.index_range().drop_front(1)) { - new_lengths[i] = orig_lengths[i - 1] * length_factor; - } - - Array<int> indices(positions.size() - 1); - Array<float> factors(positions.size() - 1); - length_parameterize::create_samples_from_sorted_lengths( - orig_lengths, new_lengths, false, indices, factors); - - Array<float3> new_positions(positions.size() - 1); - length_parameterize::linear_interpolation<float3>(positions, indices, factors, new_positions); - positions.drop_back(1).copy_from(new_positions); - positions.last() = new_last_position; - } }; void SnakeHookOperation::on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) { - SnakeHookOperatorExecutor executor; + SnakeHookOperatorExecutor executor{C}; executor.execute(*this, C, stroke_extension); } diff --git a/source/blender/editors/sculpt_paint/paint_image.cc b/source/blender/editors/sculpt_paint/paint_image.cc index a313489885d..e726fd3f338 100644 --- a/source/blender/editors/sculpt_paint/paint_image.cc +++ b/source/blender/editors/sculpt_paint/paint_image.cc @@ -736,7 +736,7 @@ void PAINT_OT_sample_color(wmOperatorType *ot) ot->poll = sample_color_poll; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER; /* properties */ PropertyRNA *prop; @@ -954,7 +954,7 @@ void PAINT_OT_brush_colors_flip(wmOperatorType *ot) ot->poll = brush_colors_flip_poll; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER; } void ED_imapaint_bucket_fill(struct bContext *C, diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index b7ec427349f..50480b8aef0 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -3132,7 +3132,7 @@ static void project_paint_face_init(const ProjPaintState *ps, } } - /* Is this UV visible from the view? - raytrace */ + /* Is this UV visible from the view? - ray-trace */ /* project_paint_PickFace is less complex, use for testing */ // if (project_paint_PickFace(ps, pixelScreenCo, w, &side) == tri_index) { if ((ps->do_occlude == false) || @@ -3222,7 +3222,7 @@ static void project_paint_face_init(const ProjPaintState *ps, float seam_subsection[4][2]; float fac1, fac2; - /* Pixelspace UVs. */ + /* Pixel-space UV's. */ float lt_puv[3][2]; lt_puv[0][0] = lt_uv_pxoffset[0][0] * ibuf->x; @@ -4492,7 +4492,8 @@ static void project_paint_begin(const bContext *C, } } - /* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */ + /* when using sub-surface or multi-resolution, + * mesh-data arrays are thrown away, we need to keep a copy. */ if (ps->is_shared_user == false) { proj_paint_state_cavity_init(ps); } @@ -6488,14 +6489,14 @@ static CustomDataLayer *proj_paint_color_attribute_create(wmOperator *op, Object { char name[MAX_NAME] = ""; float color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - AttributeDomain domain = ATTR_DOMAIN_POINT; - CustomDataType type = CD_PROP_COLOR; + eAttrDomain domain = ATTR_DOMAIN_POINT; + eCustomDataType type = CD_PROP_COLOR; if (op) { RNA_string_get(op->ptr, "name", name); RNA_float_get_array(op->ptr, "color", color); - domain = (AttributeDomain)RNA_enum_get(op->ptr, "domain"); - type = (CustomDataType)RNA_enum_get(op->ptr, "data_type"); + domain = (eAttrDomain)RNA_enum_get(op->ptr, "domain"); + type = (eCustomDataType)RNA_enum_get(op->ptr, "data_type"); } ID *id = (ID *)ob->data; diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 210cffcbcda..c3c69bf4e0a 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -912,8 +912,13 @@ PaintStroke *paint_stroke_new(bContext *C, rv3d->rflag |= RV3D_PAINTING; } - zero_v3(ups->average_stroke_accum); - ups->average_stroke_counter = 0; + /* Preserve location from last stroke while applying and resetting + * ups->average_stroke_counter to 1. + */ + if (ups->average_stroke_counter) { + mul_v3_fl(ups->average_stroke_accum, 1.0f / (float)ups->average_stroke_counter); + ups->average_stroke_counter = 1; + } /* initialize here to avoid initialization conflict with threaded strokes */ BKE_curvemapping_init(br->curve); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index fb1c8ceaa1a..fea501f20a9 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -140,7 +140,7 @@ struct NormalAnglePrecalc { static int get_vcol_elements(Mesh *me, size_t *r_elem_size) { CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); - AttributeDomain domain = BKE_id_attribute_domain(&me->id, layer); + eAttrDomain domain = BKE_id_attribute_domain(&me->id, layer); if (r_elem_size) { *r_elem_size = layer->type == CD_PROP_COLOR ? sizeof(float) * 4ULL : 4ULL; @@ -324,7 +324,7 @@ bool weight_paint_poll_ignore_tool(bContext *C) return weight_paint_poll_ex(C, false); } -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static Color vpaint_get_current_col(Scene *scene, VPaint *vp, bool secondary) { Brush *brush = BKE_paint_brush(&vp->paint); @@ -2823,11 +2823,11 @@ void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot) struct VPaintDataBase { ViewContext vc; - AttributeDomain domain; - CustomDataType type; + eAttrDomain domain; + eCustomDataType type; }; -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> struct VPaintData : public VPaintDataBase { NormalAnglePrecalc normal_angle_precalc; @@ -2855,7 +2855,7 @@ struct VPaintData : public VPaintDataBase { } smear; }; -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static void *vpaint_init_vpaint(bContext *C, wmOperator *op, Scene *scene, @@ -2949,7 +2949,7 @@ static bool vpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo return false; } - AttributeDomain domain = BKE_id_attribute_domain(&me->id, layer); + eAttrDomain domain = BKE_id_attribute_domain(&me->id, layer); void *vpd = nullptr; if (domain == ATTR_DOMAIN_POINT) { @@ -3272,7 +3272,7 @@ static void do_vpaint_brush_blur_verts(bContext *C, }); } -template<typename Color = ColorPaint4b, typename Traits, AttributeDomain domain> +template<typename Color = ColorPaint4b, typename Traits, eAttrDomain domain> static void do_vpaint_brush_smear(bContext *C, Sculpt *UNUSED(sd), VPaint *vp, @@ -3451,7 +3451,7 @@ static void do_vpaint_brush_smear(bContext *C, }); } -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd, Object *ob, Mesh *me, @@ -3541,7 +3541,7 @@ static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd, } } -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static float paint_and_tex_color_alpha(VPaint *vp, VPaintData<Color, Traits, domain> *vpd, const float v_co[3], @@ -3559,7 +3559,7 @@ static float paint_and_tex_color_alpha(VPaint *vp, return rgba[3]; } -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static void vpaint_do_draw(bContext *C, Sculpt *UNUSED(sd), VPaint *vp, @@ -3699,7 +3699,7 @@ static void vpaint_do_draw(bContext *C, }); } -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static void vpaint_do_blur(bContext *C, Sculpt *sd, VPaint *vp, @@ -3718,7 +3718,7 @@ static void vpaint_do_blur(bContext *C, } } -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static void vpaint_paint_leaves(bContext *C, Sculpt *sd, VPaint *vp, @@ -3754,7 +3754,7 @@ static void vpaint_paint_leaves(bContext *C, } } -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static void vpaint_do_paint(bContext *C, Sculpt *sd, VPaint *vp, @@ -3785,7 +3785,7 @@ static void vpaint_do_paint(bContext *C, } } -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static void vpaint_do_radial_symmetry(bContext *C, Sculpt *sd, VPaint *vp, @@ -3804,7 +3804,7 @@ static void vpaint_do_radial_symmetry(bContext *C, /* near duplicate of: sculpt.c's, * 'do_symmetrical_brush_actions' and 'wpaint_do_symmetrical_brush_actions'. */ -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static void vpaint_do_symmetrical_brush_actions( bContext *C, Sculpt *sd, VPaint *vp, VPaintData<Color, Traits, domain> *vpd, Object *ob) { @@ -3851,7 +3851,7 @@ static void vpaint_do_symmetrical_brush_actions( cache->is_last_valid = true; } -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static void vpaint_stroke_update_step_intern(bContext *C, PaintStroke *stroke, PointerRNA *itemptr) { Scene *scene = CTX_data_scene(C); @@ -3939,7 +3939,7 @@ static void vpaint_stroke_update_step(bContext *C, } } -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static void vpaint_free_vpaintdata(Object *UNUSED(ob), void *_vpd) { VPaintData<Color, Traits, domain> *vpd = static_cast<VPaintData<Color, Traits, domain> *>(_vpd); @@ -4096,7 +4096,7 @@ void PAINT_OT_vertex_paint(wmOperatorType *ot) /** \name Set Vertex Colors Operator * \{ */ -template<typename Color, typename Traits, AttributeDomain domain> +template<typename Color, typename Traits, eAttrDomain domain> static bool vertex_color_set(Object *ob, ColorPaint4f paintcol_in, Color *color_layer) { Mesh *me; @@ -4164,7 +4164,7 @@ static bool paint_object_attributes_active_color_fill_ex(Object *ob, me->editflag &= ~ME_EDIT_PAINT_FACE_SEL; me->editflag &= ~ME_EDIT_PAINT_VERT_SEL; } - AttributeDomain domain = BKE_id_attribute_domain(&me->id, layer); + eAttrDomain domain = BKE_id_attribute_domain(&me->id, layer); bool ok = false; if (domain == ATTR_DOMAIN_POINT) { if (layer->type == CD_PROP_COLOR) { diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index c7a662df39a..b3e6c34195b 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -50,6 +50,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_geometry.h" #include "ED_object.h" #include "ED_sculpt.h" #include "ED_undo.h" @@ -105,7 +106,7 @@ typedef struct UndoSculpt { } UndoSculpt; typedef struct SculptAttrRef { - AttributeDomain domain; + eAttrDomain domain; int type; char name[MAX_CUSTOMDATA_LAYER_NAME]; bool was_set; @@ -1569,6 +1570,24 @@ static void sculpt_undo_set_active_layer(struct bContext *C, SculptAttrRef *attr CustomDataLayer *layer; layer = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain); + /* Temporary fix for T97408. This is a fundamental + * bug in the undo stack; the operator code needs to push + * an extra undo step before running an operator if a + * non-memfile undo system is active. + * + * For now, detect if the layer does exist but with a different + * domain and just unconvert it. + */ + if (!layer) { + layer = BKE_id_attribute_search(&me->id, attr->name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL); + eAttrDomain domain = layer ? BKE_id_attribute_domain(&me->id, layer) : ATTR_DOMAIN_NUM; + + if (layer && ED_geometry_attribute_convert( + me, attr->name, layer->type, domain, attr->type, attr->domain)) { + layer = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain); + } + } + if (!layer) { /* Memfile undo killed the layer; re-create it. */ CustomData *cdata = attr->domain == ATTR_DOMAIN_POINT ? &me->vdata : &me->ldata; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index cfbbc1a1b45..7417f1bdb12 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -3075,7 +3075,7 @@ static int filelist_readjob_list_dir(const char *root, } target = entry->redirection_path; #ifdef WIN32 - /* On Windows don't show ".lnk" extension for valid shortcuts. */ + /* On Windows don't show `.lnk` extension for valid shortcuts. */ BLI_path_extension_replace(entry->relpath, FILE_MAXDIR, ""); #endif } diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 10cde239987..310c688383b 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -890,7 +890,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) continue; } - /* Exclude "all my files" as it makes no sense in blender fileselector */ + /* Exclude "all my files" as it makes no sense in blender file-selector. */ /* Exclude "airdrop" if wlan not active as it would show "" ) */ if (!strstr(line, "myDocuments.cannedSearch") && (*line != '\0')) { fsmenu_insert_entry( diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 208928afc1f..d0c21f85472 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -845,7 +845,10 @@ void uiTemplateImage(uiLayout *layout, row = uiLayoutRow(row, true); uiLayoutSetEnabled(row, is_packed == false); - uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE); + + prop = RNA_struct_find_property(&imaptr, "filepath"); + uiDefAutoButR(block, &imaptr, prop, -1, "", ICON_NONE, 0, 0, 200, UI_UNIT_Y); + uiItemO(row, "", ICON_FILEBROWSER, "image.file_browse"); uiItemO(row, "", ICON_FILE_REFRESH, "image.reload"); } diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index 2322420069e..364bec1377d 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -49,6 +49,7 @@ void IMAGE_OT_new(struct wmOperatorType *ot); * Called by other space types too. */ void IMAGE_OT_open(struct wmOperatorType *ot); +void IMAGE_OT_file_browse(struct wmOperatorType *ot); /** * Called by other space types too. */ diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index bd1cb3a345e..0761568e480 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -197,6 +197,20 @@ static ImageUser *image_user_from_context(const bContext *C) return (sima) ? &sima->iuser : NULL; } +static ImageUser image_user_from_active_tile(Image *ima) +{ + ImageUser iuser; + BKE_imageuser_default(&iuser); + + /* Use the file associated with the active tile. Otherwise use the first tile. */ + if (ima && ima->source == IMA_SRC_TILED) { + const ImageTile *active = (ImageTile *)BLI_findlink(&ima->tiles, ima->active_tile_index); + iuser.tile = active ? active->tile_number : ((ImageTile *)ima->tiles.first)->tile_number; + } + + return iuser; +} + static bool image_from_context_has_data_poll(bContext *C) { Image *ima = image_from_context(C); @@ -214,13 +228,14 @@ static bool image_from_context_has_data_poll(bContext *C) } /** - * Use this when the image buffer is accessed without the image user. + * Use this when the image buffer is accessing the active tile without the image user. */ -static bool image_from_context_has_data_poll_no_image_user(bContext *C) +static bool image_from_context_has_data_poll_active_tile(bContext *C) { Image *ima = image_from_context(C); + ImageUser iuser = image_user_from_active_tile(ima); - return BKE_image_has_ibuf(ima, NULL); + return BKE_image_has_ibuf(ima, &iuser); } static bool image_not_packed_poll(bContext *C) @@ -1446,7 +1461,7 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( image_open_init(C, op); - /* show multiview save options only if scene has multiviews */ + /* Show multi-view save options only if scene has multi-views. */ PropertyRNA *prop; prop = RNA_struct_find_property(op->ptr, "show_multiview"); RNA_property_boolean_set(op->ptr, prop, (scene->r.scemode & R_MULTIVIEW) != 0); @@ -1535,6 +1550,115 @@ void IMAGE_OT_open(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ +/** \name Browse Image Operator + * \{ */ + +static int image_file_browse_exec(bContext *C, wmOperator *op) +{ + Image *ima = op->customdata; + if (ima == NULL) { + return OPERATOR_CANCELLED; + } + + char filepath[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", filepath); + + /* If loading into a tiled texture, ensure that the filename is tokenized. */ + if (ima->source == IMA_SRC_TILED) { + char *filename = (char *)BLI_path_basename(filepath); + BKE_image_ensure_tile_token(filename); + } + + PointerRNA imaptr; + PropertyRNA *imaprop; + RNA_id_pointer_create(&ima->id, &imaptr); + imaprop = RNA_struct_find_property(&imaptr, "filepath"); + + RNA_property_string_set(&imaptr, imaprop, filepath); + RNA_property_update(C, &imaptr, imaprop); + + return OPERATOR_FINISHED; +} + +static int image_file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Image *ima = image_from_context(C); + if (!ima) { + return OPERATOR_CANCELLED; + } + + char filepath[FILE_MAX]; + BLI_strncpy(filepath, ima->filepath, sizeof(filepath)); + + /* Shift+Click to open the file, Alt+Click to browse a folder in the OS's browser. */ + if (event->modifier & (KM_SHIFT | KM_ALT)) { + wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true); + PointerRNA props_ptr; + + if (event->modifier & KM_ALT) { + char *lslash = (char *)BLI_path_slash_rfind(filepath); + if (lslash) { + *lslash = '\0'; + } + } + else if (ima->source == IMA_SRC_TILED) { + ImageUser iuser = image_user_from_active_tile(ima); + BKE_image_user_file_path(&iuser, ima, filepath); + } + + WM_operator_properties_create_ptr(&props_ptr, ot); + RNA_string_set(&props_ptr, "filepath", filepath); + WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr, NULL); + WM_operator_properties_free(&props_ptr); + + return OPERATOR_CANCELLED; + } + + /* The image is typically passed to the operator via layout/button context (e.g. + * #uiLayoutSetContextPointer()). The File Browser doesn't support restoring this context + * when calling `exec()` though, so we have to pass it the image via custom data. */ + op->customdata = ima; + + image_filesel(C, op, filepath); + + return OPERATOR_RUNNING_MODAL; +} + +static bool image_file_browse_poll(bContext *C) +{ + return image_from_context(C) != NULL; +} + +void IMAGE_OT_file_browse(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Browse Image"; + ot->description = + "Open an image file browser, hold Shift to open the file, Alt to browse containing " + "directory"; + ot->idname = "IMAGE_OT_file_browse"; + + /* api callbacks */ + ot->exec = image_file_browse_exec; + ot->invoke = image_file_browse_invoke; + ot->poll = image_file_browse_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_filesel(ot, + FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, + FILE_SPECIAL, + FILE_OPENFILE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, + FILE_DEFAULTDISPLAY, + FILE_SORT_DEFAULT); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Match Movie Length Operator * \{ */ @@ -1696,7 +1820,6 @@ static void image_save_options_from_op(Main *bmain, ImageSaveOptions *opts, wmOp RNA_boolean_get(op->ptr, "copy")); opts->save_as_render = (RNA_struct_find_property(op->ptr, "save_as_render") && RNA_boolean_get(op->ptr, "save_as_render")); - opts->do_newpath = true; } static bool save_image_op( @@ -1733,6 +1856,8 @@ static ImageSaveData *image_save_as_init(bContext *C, wmOperator *op) return NULL; } + isd->opts.do_newpath = true; + if (!RNA_struct_property_is_set(op->ptr, "filepath")) { RNA_string_set(op->ptr, "filepath", isd->opts.filepath); } @@ -2573,7 +2698,8 @@ void IMAGE_OT_new(wmOperatorType *ot) static int image_flip_exec(bContext *C, wmOperator *op) { Image *ima = image_from_context(C); - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + ImageUser iuser = image_user_from_active_tile(ima); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); SpaceImage *sima = CTX_wm_space_image(C); const bool is_paint = ((sima != NULL) && (sima->mode == SI_MODE_PAINT)); @@ -2670,7 +2796,7 @@ void IMAGE_OT_flip(wmOperatorType *ot) /* api callbacks */ ot->exec = image_flip_exec; - ot->poll = image_from_context_has_data_poll_no_image_user; + ot->poll = image_from_context_has_data_poll_active_tile; /* properties */ PropertyRNA *prop; @@ -2693,7 +2819,8 @@ void IMAGE_OT_flip(wmOperatorType *ot) static int image_invert_exec(bContext *C, wmOperator *op) { Image *ima = image_from_context(C); - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + ImageUser iuser = image_user_from_active_tile(ima); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); SpaceImage *sima = CTX_wm_space_image(C); const bool is_paint = ((sima != NULL) && (sima->mode == SI_MODE_PAINT)); @@ -2791,7 +2918,7 @@ void IMAGE_OT_invert(wmOperatorType *ot) /* api callbacks */ ot->exec = image_invert_exec; - ot->poll = image_from_context_has_data_poll_no_image_user; + ot->poll = image_from_context_has_data_poll_active_tile; /* properties */ prop = RNA_def_boolean(ot->srna, "invert_r", 0, "Red", "Invert red channel"); @@ -2816,9 +2943,10 @@ void IMAGE_OT_invert(wmOperatorType *ot) static int image_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { Image *ima = image_from_context(C); + ImageUser iuser = image_user_from_active_tile(ima); PropertyRNA *prop = RNA_struct_find_property(op->ptr, "size"); if (!RNA_property_is_set(op->ptr, prop)) { - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); const int size[2] = {ibuf->x, ibuf->y}; RNA_property_int_set_array(op->ptr, prop, size); BKE_image_release_ibuf(ima, ibuf, NULL); @@ -2829,7 +2957,8 @@ static int image_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED static int image_scale_exec(bContext *C, wmOperator *op) { Image *ima = image_from_context(C); - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + ImageUser iuser = image_user_from_active_tile(ima); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); SpaceImage *sima = CTX_wm_space_image(C); const bool is_paint = ((sima != NULL) && (sima->mode == SI_MODE_PAINT)); @@ -2879,7 +3008,7 @@ void IMAGE_OT_resize(wmOperatorType *ot) /* api callbacks */ ot->invoke = image_scale_invoke; ot->exec = image_scale_exec; - ot->poll = image_from_context_has_data_poll_no_image_user; + ot->poll = image_from_context_has_data_poll_active_tile; /* properties */ RNA_def_int_vector(ot->srna, "size", 2, NULL, 1, INT_MAX, "Size", "", 1, SHRT_MAX); diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c index 1fd9fde084b..a7a8bde1115 100644 --- a/source/blender/editors/space_image/image_undo.c +++ b/source/blender/editors/space_image/image_undo.c @@ -287,7 +287,7 @@ static void ptile_restore_runtime_list(ListBase *paint_tiles) ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */ } if (ibuf->mipmap[0]) { - ibuf->userflags |= IB_MIPMAP_INVALID; /* force mip-map recreation. */ + ibuf->userflags |= IB_MIPMAP_INVALID; /* Force MIP-MAP recreation. */ } ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 63f919a1713..9832fcfdb70 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -199,6 +199,7 @@ static void image_operatortypes(void) WM_operatortype_append(IMAGE_OT_new); WM_operatortype_append(IMAGE_OT_open); + WM_operatortype_append(IMAGE_OT_file_browse); WM_operatortype_append(IMAGE_OT_match_movie_length); WM_operatortype_append(IMAGE_OT_replace); WM_operatortype_append(IMAGE_OT_reload); diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 2aa9b347ed7..81520445000 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -1004,7 +1004,7 @@ static int nlaedit_add_meta_exec(bContext *C, wmOperator *UNUSED(op)) NlaStrip *strip; if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { - /* No making metastrips in non-local tracks of override data. */ + /* No making meta-strips in non-local tracks of override data. */ continue; } @@ -1078,7 +1078,7 @@ static int nlaedit_remove_meta_exec(bContext *C, wmOperator *UNUSED(op)) NlaTrack *nlt = (NlaTrack *)ale->data; if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { - /* No removing metastrips from non-local tracks of override data. */ + /* No removing meta-strips from non-local tracks of override data. */ continue; } @@ -1714,7 +1714,7 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op) BKE_nlatrack_add_strip(nlt, sb, is_liboverride); } - /* clear (temp) metastrips */ + /* Clear (temp) meta-strips. */ BKE_nlastrips_clear_metas(&nlt->strips, 0, 1); } diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index e0ff4212a94..7003d51b2b6 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -66,6 +66,7 @@ #include "NOD_geometry_nodes_eval_log.hh" #include "NOD_node_declaration.hh" +#include "NOD_socket_declarations_geometry.hh" #include "FN_field.hh" #include "FN_field_cpp_type.hh" @@ -75,7 +76,7 @@ using blender::GPointer; using blender::fn::GField; namespace geo_log = blender::nodes::geometry_nodes_eval_log; -using geo_log::NamedAttributeUsage; +using geo_log::eNamedAttrUsage; extern "C" { /* XXX interface.h */ @@ -871,7 +872,8 @@ static void create_inspection_string_for_gfield(const geo_log::GFieldValueLog &v } static void create_inspection_string_for_geometry(const geo_log::GeometryValueLog &value_log, - std::stringstream &ss) + std::stringstream &ss, + const nodes::decl::Geometry *geometry) { Span<GeometryComponentType> component_types = value_log.component_types(); if (component_types.is_empty()) { @@ -938,6 +940,45 @@ static void create_inspection_string_for_geometry(const geo_log::GeometryValueLo } } } + + /* If the geometry declaration is null, as is the case for input to group output, + * or it is an output socket don't show supported types. */ + if (geometry == nullptr || geometry->in_out() == SOCK_OUT) { + return; + } + + Span<GeometryComponentType> supported_types = geometry->supported_types(); + if (supported_types.is_empty()) { + ss << ".\n\n" << TIP_("Supported: All Types"); + return; + } + + ss << ".\n\n" << TIP_("Supported: "); + for (GeometryComponentType type : supported_types) { + switch (type) { + case GEO_COMPONENT_TYPE_MESH: { + ss << TIP_("Mesh"); + break; + } + case GEO_COMPONENT_TYPE_POINT_CLOUD: { + ss << TIP_("Point Cloud"); + break; + } + case GEO_COMPONENT_TYPE_CURVE: { + ss << TIP_("Curve"); + break; + } + case GEO_COMPONENT_TYPE_INSTANCES: { + ss << TIP_("Instances"); + break; + } + case GEO_COMPONENT_TYPE_VOLUME: { + ss << TIP_("Volume"); + break; + } + } + ss << ((type == supported_types.last()) ? "" : ", "); + } } static std::optional<std::string> create_socket_inspection_string(bContext *C, @@ -970,7 +1011,10 @@ static std::optional<std::string> create_socket_inspection_string(bContext *C, } else if (const geo_log::GeometryValueLog *geo_value_log = dynamic_cast<const geo_log::GeometryValueLog *>(value_log)) { - create_inspection_string_for_geometry(*geo_value_log, ss); + create_inspection_string_for_geometry( + *geo_value_log, + ss, + dynamic_cast<const nodes::decl::Geometry *>(socket.runtime->declaration)); } return ss.str(); @@ -1695,7 +1739,7 @@ struct NodeExtraInfoRow { }; struct NamedAttributeTooltipArg { - Map<std::string, NamedAttributeUsage> usage_by_attribute; + Map<std::string, eNamedAttrUsage> usage_by_attribute; }; static char *named_attribute_tooltip(bContext *UNUSED(C), void *argN, const char *UNUSED(tip)) @@ -1707,7 +1751,7 @@ static char *named_attribute_tooltip(bContext *UNUSED(C), void *argN, const char struct NameWithUsage { StringRefNull name; - NamedAttributeUsage usage; + eNamedAttrUsage usage; }; Vector<NameWithUsage> sorted_used_attribute; @@ -1722,16 +1766,16 @@ static char *named_attribute_tooltip(bContext *UNUSED(C), void *argN, const char for (const NameWithUsage &attribute : sorted_used_attribute) { const StringRefNull name = attribute.name; - const NamedAttributeUsage usage = attribute.usage; + const eNamedAttrUsage usage = attribute.usage; ss << " \u2022 \"" << name << "\": "; Vector<std::string> usages; - if ((usage & NamedAttributeUsage::Read) != NamedAttributeUsage::None) { + if ((usage & eNamedAttrUsage::Read) != eNamedAttrUsage::None) { usages.append(TIP_("read")); } - if ((usage & NamedAttributeUsage::Write) != NamedAttributeUsage::None) { + if ((usage & eNamedAttrUsage::Write) != eNamedAttrUsage::None) { usages.append(TIP_("write")); } - if ((usage & NamedAttributeUsage::Remove) != NamedAttributeUsage::None) { + if ((usage & eNamedAttrUsage::Remove) != eNamedAttrUsage::None) { usages.append(TIP_("remove")); } for (const int i : usages.index_range()) { @@ -1749,7 +1793,7 @@ static char *named_attribute_tooltip(bContext *UNUSED(C), void *argN, const char } static NodeExtraInfoRow row_from_used_named_attribute( - const Map<std::string, NamedAttributeUsage> &usage_by_attribute_name) + const Map<std::string, eNamedAttrUsage> &usage_by_attribute_name) { const int attributes_num = usage_by_attribute_name.size(); @@ -1777,7 +1821,7 @@ static std::optional<NodeExtraInfoRow> node_get_accessed_attributes_row(const Sp return std::nullopt; } - Map<std::string, NamedAttributeUsage> usage_by_attribute; + Map<std::string, eNamedAttrUsage> usage_by_attribute; tree_log->foreach_node_log([&](const geo_log::NodeLog &node_log) { for (const geo_log::UsedNamedAttribute &used_attribute : node_log.used_named_attributes()) { usage_by_attribute.lookup_or_add_as(used_attribute.name, @@ -1807,7 +1851,7 @@ static std::optional<NodeExtraInfoRow> node_get_accessed_attributes_row(const Sp if (node_log == nullptr) { return std::nullopt; } - Map<std::string, NamedAttributeUsage> usage_by_attribute; + Map<std::string, eNamedAttrUsage> usage_by_attribute; for (const geo_log::UsedNamedAttribute &used_attribute : node_log->used_named_attributes()) { usage_by_attribute.lookup_or_add_as(used_attribute.name, used_attribute.usage) |= used_attribute.usage; diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index ab80a44d636..ffc9befc81c 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -15,6 +15,7 @@ #include "DNA_text_types.h" #include "DNA_world_types.h" +#include "BKE_callbacks.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_image.h" @@ -275,6 +276,7 @@ static void compo_startjob(void *cjv, // XXX BIF_store_spare(); /* 1 is do_previews */ + BKE_callback_exec_id(cj->bmain, &scene->id, BKE_CB_EVT_COMPOSITE_PRE); if ((cj->scene->r.scemode & R_MULTIVIEW) == 0) { ntreeCompositExecTree(cj->scene, ntree, &cj->scene->r, false, true, ""); @@ -293,6 +295,22 @@ static void compo_startjob(void *cjv, ntree->progress = nullptr; } +static void compo_canceljob(void *cjv) +{ + CompoJob *cj = (CompoJob *)cjv; + Main *bmain = cj->bmain; + Scene *scene = cj->scene; + BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_COMPOSITE_CANCEL); +} + +static void compo_completejob(void *cjv) +{ + CompoJob *cj = (CompoJob *)cjv; + Main *bmain = cj->bmain; + Scene *scene = cj->scene; + BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_COMPOSITE_POST); +} + /** \} */ } // namespace blender::ed::space_node @@ -339,7 +357,13 @@ void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene /* setup job */ WM_jobs_customdata_set(wm_job, cj, compo_freejob); WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_COMPO_RESULT, NC_SCENE | ND_COMPO_RESULT); - WM_jobs_callbacks(wm_job, compo_startjob, compo_initjob, compo_updatejob, nullptr); + WM_jobs_callbacks_ex(wm_job, + compo_startjob, + compo_initjob, + compo_updatejob, + nullptr, + compo_completejob, + compo_canceljob); WM_jobs_start(CTX_wm_manager(C), wm_job); } diff --git a/source/blender/editors/space_node/node_geometry_attribute_search.cc b/source/blender/editors/space_node/node_geometry_attribute_search.cc index 9c0172cfabf..f08e23c8371 100644 --- a/source/blender/editors/space_node/node_geometry_attribute_search.cc +++ b/source/blender/editors/space_node/node_geometry_attribute_search.cc @@ -82,8 +82,10 @@ static Vector<const GeometryAttributeInfo *> get_attribute_info_from_context( if (const geo_log::GeometryValueLog *geo_value_log = dynamic_cast<const geo_log::GeometryValueLog *>(value_log)) { for (const GeometryAttributeInfo &attribute : geo_value_log->attributes()) { - if (names.add(attribute.name)) { - attributes.append(&attribute); + if (bke::allow_procedural_attribute_access(attribute.name)) { + if (names.add(attribute.name)) { + attributes.append(&attribute); + } } } } @@ -126,7 +128,7 @@ static void attribute_search_update_fn( * Some custom data types don't correspond to node types and therefore can't be * used by the named attribute input node. Find the best option or fallback to float. */ -static CustomDataType data_type_in_attribute_input_node(const CustomDataType type) +static eCustomDataType data_type_in_attribute_input_node(const eCustomDataType type) { switch (type) { case CD_PROP_FLOAT: @@ -185,7 +187,7 @@ static void attribute_search_exec_fn(bContext *C, void *data_v, void *item_v) /* For the attribute input node, also adjust the type and links connected to the output. */ if (node->type == GEO_NODE_INPUT_NAMED_ATTRIBUTE && item->data_type.has_value()) { NodeGeometryInputNamedAttribute &storage = *(NodeGeometryInputNamedAttribute *)node->storage; - const CustomDataType new_type = data_type_in_attribute_input_node(*item->data_type); + const eCustomDataType new_type = data_type_in_attribute_input_node(*item->data_type); if (new_type != storage.data_type) { storage.data_type = new_type; /* Make the output socket with the new type on the attribute input node active. */ diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 5796a712205..e10bedb18f4 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -454,7 +454,7 @@ static bool socket_can_be_viewed(const OutputSocketRef &socket) SOCK_RGBA); } -static CustomDataType socket_type_to_custom_data_type(const eNodeSocketDatatype socket_type) +static eCustomDataType socket_type_to_custom_data_type(const eNodeSocketDatatype socket_type) { switch (socket_type) { case SOCK_FLOAT: @@ -491,7 +491,7 @@ static bNodeSocket *node_link_viewer_get_socket(bNodeTree &ntree, return viewer_socket; } NodeGeometryViewer *storage = (NodeGeometryViewer *)viewer_node.storage; - const CustomDataType data_type = socket_type_to_custom_data_type( + const eCustomDataType data_type = socket_type_to_custom_data_type( (eNodeSocketDatatype)src_socket.type); BLI_assert(data_type != CD_AUTO_FROM_NAME); storage->data_type = data_type; diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 10c6e828e96..ea6d3351eaa 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -191,10 +191,11 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type) } for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if ((ELEM(type, -1, seq->type)) && (seq->enddisp < timeline_frame) && - (timeline_frame - seq->enddisp < proximity)) { + const int strip_end = SEQ_time_right_handle_frame_get(seq); + if ((ELEM(type, -1, seq->type)) && (strip_end < timeline_frame) && + (timeline_frame - strip_end < proximity)) { tgt = seq; - proximity = timeline_frame - seq->enddisp; + proximity = timeline_frame - strip_end; } } @@ -785,7 +786,6 @@ static void seq_build_proxy(bContext *C, SeqCollection *movie_strips) } static void sequencer_add_movie_clamp_sound_strip_length(Scene *scene, - ListBase *seqbase, Sequence *seq_movie, Sequence *seq_sound) { @@ -793,9 +793,8 @@ static void sequencer_add_movie_clamp_sound_strip_length(Scene *scene, return; } - SEQ_time_right_handle_frame_set(seq_sound, SEQ_time_right_handle_frame_get(seq_movie)); - SEQ_time_left_handle_frame_set(seq_sound, SEQ_time_left_handle_frame_get(seq_movie)); - SEQ_time_update_sequence(scene, seqbase, seq_sound); + SEQ_time_right_handle_frame_set(scene, seq_sound, SEQ_time_right_handle_frame_get(seq_movie)); + SEQ_time_left_handle_frame_set(scene, seq_sound, SEQ_time_left_handle_frame_get(seq_movie)); } static void sequencer_add_movie_multiple_strips(bContext *C, @@ -833,7 +832,7 @@ static void sequencer_add_movie_multiple_strips(bContext *C, else { if (RNA_boolean_get(op->ptr, "sound")) { seq_sound = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data); - sequencer_add_movie_clamp_sound_strip_length(scene, ed->seqbasep, seq_movie, seq_sound); + sequencer_add_movie_clamp_sound_strip_length(scene, seq_movie, seq_sound); if (seq_sound) { /* The video has sound, shift the video strip up a channel to make room for the sound @@ -842,7 +841,8 @@ static void sequencer_add_movie_multiple_strips(bContext *C, } } - load_data->start_frame += seq_movie->enddisp - seq_movie->startdisp; + load_data->start_frame += SEQ_time_right_handle_frame_get(seq_movie) - + SEQ_time_left_handle_frame_get(seq_movie); if (overlap_shuffle_override) { has_seq_overlap |= seq_load_apply_generic_options_only_test_overlap( C, op, seq_sound, strip_col); @@ -890,7 +890,7 @@ static bool sequencer_add_movie_single_strip(bContext *C, } if (RNA_boolean_get(op->ptr, "sound")) { seq_sound = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data); - sequencer_add_movie_clamp_sound_strip_length(scene, ed->seqbasep, seq_movie, seq_sound); + sequencer_add_movie_clamp_sound_strip_length(scene, seq_movie, seq_sound); if (seq_sound) { /* The video has sound, shift the video strip up a channel to make room for the sound * strip. */ @@ -1073,7 +1073,8 @@ static void sequencer_add_sound_multiple_strips(bContext *C, } else { seq_load_apply_generic_options(C, op, seq); - load_data->start_frame += seq->enddisp - seq->startdisp; + load_data->start_frame += SEQ_time_right_handle_frame_get(seq) - + SEQ_time_left_handle_frame_get(seq); } } RNA_END; @@ -1300,8 +1301,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) /* Adjust length. */ if (load_data.image.len == 1) { - SEQ_time_right_handle_frame_set(seq, load_data.image.end_frame); - SEQ_time_update_sequence(scene, SEQ_active_seqbase_get(ed), seq); + SEQ_time_right_handle_frame_set(scene, seq, load_data.image.end_frame); } seq_load_apply_generic_options(C, op, seq); diff --git a/source/blender/editors/space_sequencer/sequencer_drag_drop.c b/source/blender/editors/space_sequencer/sequencer_drag_drop.c index 645c0dc9a1d..8dadb9360e3 100644 --- a/source/blender/editors/space_sequencer/sequencer_drag_drop.c +++ b/source/blender/editors/space_sequencer/sequencer_drag_drop.c @@ -231,9 +231,8 @@ static void update_overlay_strip_poistion_data(bContext *C, const int mval[2]) else { /* Check if there is a strip that would intersect with the new strip(s). */ coords->is_intersecting = false; - Sequence dummy_seq = {.machine = coords->channel, - .startdisp = coords->start_frame, - .enddisp = coords->start_frame + coords->strip_len}; + Sequence dummy_seq = { + .machine = coords->channel, .start = coords->start_frame, .len = coords->strip_len}; Editing *ed = SEQ_editing_get(scene); for (int i = 0; i < coords->channel_len && !coords->is_intersecting; i++) { diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 02e77732e02..25701c323b9 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -617,8 +617,8 @@ static void drawmeta_contents(Scene *scene, /* Draw only immediate children (1 level depth). */ for (seq = meta_seqbase->first; seq; seq = seq->next) { - const int startdisp = seq->startdisp + offset; - const int enddisp = seq->enddisp + offset; + const int startdisp = SEQ_time_left_handle_frame_get(seq) + offset; + const int enddisp = SEQ_time_right_handle_frame_get(seq) + offset; if ((startdisp > x2 || enddisp < x1) == 0) { float y_chan = (seq->machine - chan_min) / (float)(chan_range)*draw_range; @@ -668,7 +668,10 @@ float sequence_handle_size_get_clamped(Sequence *seq, const float pixelx) const float maxhandle = (pixelx * SEQ_HANDLE_SIZE) * U.pixelsize; /* Ensure that handle is not wider, than quarter of strip. */ - return min_ff(maxhandle, ((float)(seq->enddisp - seq->startdisp) / 4.0f)); + return min_ff( + maxhandle, + ((float)(SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq)) / + 4.0f)); } /* Draw a handle, on left or right side of strip. */ @@ -686,8 +689,8 @@ static void draw_seq_handle(View2D *v2d, uint whichsel = 0; uchar col[4]; - x1 = seq->startdisp; - x2 = seq->enddisp; + x1 = SEQ_time_left_handle_frame_get(seq); + x2 = SEQ_time_right_handle_frame_get(seq); y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; y2 = seq->machine + SEQ_STRIP_OFSTOP; @@ -739,7 +742,11 @@ static void draw_seq_handle(View2D *v2d, BLF_set_default(); /* Calculate if strip is wide enough for showing the labels. */ - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d%d", seq->startdisp, seq->enddisp); + numstr_len = BLI_snprintf_rlen(numstr, + sizeof(numstr), + "%d%d", + SEQ_time_left_handle_frame_get(seq), + SEQ_time_right_handle_frame_get(seq)); float tot_width = BLF_width(fontid, numstr, numstr_len); if ((x2 - x1) / pixelx > 20 + tot_width) { @@ -747,12 +754,14 @@ static void draw_seq_handle(View2D *v2d, float text_margin = 1.2f * handsize_clamped; if (direction == SEQ_LEFTHANDLE) { - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", seq->startdisp); + numstr_len = BLI_snprintf_rlen( + numstr, sizeof(numstr), "%d", SEQ_time_left_handle_frame_get(seq)); x1 += text_margin; y1 += 0.09f; } else { - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", seq->enddisp - 1); + numstr_len = BLI_snprintf_rlen( + numstr, sizeof(numstr), "%d", SEQ_time_right_handle_frame_get(seq) - 1); x1 = x2 - (text_margin + pixelx * BLF_width(fontid, numstr, numstr_len)); y1 += 0.09f; } @@ -913,7 +922,8 @@ static size_t draw_seq_text_get_overlay_string(SpaceSeq *sseq, char strip_duration_text[16]; if (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_DURATION) { - const int strip_duration = seq->enddisp - seq->startdisp; + const int strip_duration = SEQ_time_right_handle_frame_get(seq) - + SEQ_time_left_handle_frame_get(seq); SNPRINTF(strip_duration_text, "%d", strip_duration); if (i != 0) { text_array[i++] = text_sep; @@ -980,8 +990,8 @@ static void draw_sequence_extensions_overlay( float x1, x2, y1, y2; uchar col[4], blend_col[3]; - x1 = seq->startdisp; - x2 = seq->enddisp; + x1 = SEQ_time_left_handle_frame_get(seq); + x2 = SEQ_time_right_handle_frame_get(seq); y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; y2 = seq->machine + SEQ_STRIP_OFSTOP; @@ -1038,15 +1048,19 @@ static void draw_color_strip_band( immUniformColor4ubv(col); - immRectf(pos, seq->startdisp, y1, seq->enddisp, text_margin_y); + immRectf(pos, + SEQ_time_left_handle_frame_get(seq), + y1, + SEQ_time_right_handle_frame_get(seq), + text_margin_y); /* 1px line to better separate the color band. */ UI_GetColorPtrShade3ubv(col, col, -20); immUniformColor4ubv(col); immBegin(GPU_PRIM_LINES, 2); - immVertex2f(pos, seq->startdisp, text_margin_y); - immVertex2f(pos, seq->enddisp, text_margin_y); + immVertex2f(pos, SEQ_time_left_handle_frame_get(seq), text_margin_y); + immVertex2f(pos, SEQ_time_right_handle_frame_get(seq), text_margin_y); immEnd(); GPU_blend(GPU_BLEND_NONE); @@ -1111,12 +1125,12 @@ static void draw_seq_background(Scene *scene, immUniformColor4ubv(col); if (SEQ_time_has_left_still_frames(seq)) { - const float content_start = min_ff(seq->enddisp, seq->start); - immRectf(pos, seq->startdisp, y1, content_start, y2); + const float content_start = min_ff(SEQ_time_right_handle_frame_get(seq), seq->start); + immRectf(pos, SEQ_time_left_handle_frame_get(seq), y1, content_start, y2); } if (SEQ_time_has_right_still_frames(seq)) { - const float content_end = max_ff(seq->startdisp, seq->start + seq->len); - immRectf(pos, content_end, y1, seq->enddisp, y2); + const float content_end = max_ff(SEQ_time_left_handle_frame_get(seq), seq->start + seq->len); + immRectf(pos, content_end, y1, SEQ_time_right_handle_frame_get(seq), y2); } } @@ -1333,14 +1347,15 @@ static void draw_seq_strip(const bContext *C, SEQ_TIMELINE_SHOW_STRIP_COLOR_TAG); /* Draw strip body. */ - x1 = SEQ_time_has_left_still_frames(seq) ? seq->start : seq->startdisp; + x1 = SEQ_time_has_left_still_frames(seq) ? seq->start : SEQ_time_left_handle_frame_get(seq); y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; - x2 = SEQ_time_has_right_still_frames(seq) ? (seq->start + seq->len) : seq->enddisp; + x2 = SEQ_time_has_right_still_frames(seq) ? (seq->start + seq->len) : + SEQ_time_right_handle_frame_get(seq); y2 = seq->machine + SEQ_STRIP_OFSTOP; /* Limit body to strip bounds. Meta strip can end up with content outside of strip range. */ - x1 = min_ff(x1, seq->enddisp); - x2 = max_ff(x2, seq->startdisp); + x1 = min_ff(x1, SEQ_time_right_handle_frame_get(seq)); + x2 = max_ff(x2, SEQ_time_left_handle_frame_get(seq)); float text_margin_y; bool y_threshold; @@ -1380,8 +1395,8 @@ static void draw_seq_strip(const bContext *C, } immUnbindProgram(); - x1 = seq->startdisp; - x2 = seq->enddisp; + x1 = SEQ_time_left_handle_frame_get(seq); + x2 = SEQ_time_right_handle_frame_get(seq); if ((seq->type == SEQ_TYPE_META) || ((seq->type == SEQ_TYPE_SCENE) && (seq->flag & SEQ_SCENE_STRIPS))) { @@ -1471,23 +1486,23 @@ static void draw_effect_inputs_highlight(Sequence *seq) immUniformColor4ub(255, 255, 255, 48); immRectf(pos, - seq1->startdisp, + SEQ_time_left_handle_frame_get(seq1), seq1->machine + SEQ_STRIP_OFSBOTTOM, - seq1->enddisp, + SEQ_time_right_handle_frame_get(seq1), seq1->machine + SEQ_STRIP_OFSTOP); if (seq2 && seq2 != seq1) { immRectf(pos, - seq2->startdisp, + SEQ_time_left_handle_frame_get(seq2), seq2->machine + SEQ_STRIP_OFSBOTTOM, - seq2->enddisp, + SEQ_time_right_handle_frame_get(seq2), seq2->machine + SEQ_STRIP_OFSTOP); } if (seq3 && !ELEM(seq3, seq1, seq2)) { immRectf(pos, - seq3->startdisp, + SEQ_time_left_handle_frame_get(seq3), seq3->machine + SEQ_STRIP_OFSBOTTOM, - seq3->enddisp, + SEQ_time_right_handle_frame_get(seq3), seq3->machine + SEQ_STRIP_OFSTOP); } immUnbindProgram(); @@ -2081,10 +2096,10 @@ static int sequencer_draw_get_transform_preview_frame(Scene *scene) int preview_frame; if (last_seq->flag & SEQ_RIGHTSEL) { - preview_frame = last_seq->enddisp - 1; + preview_frame = SEQ_time_right_handle_frame_get(last_seq) - 1; } else { - preview_frame = last_seq->startdisp; + preview_frame = SEQ_time_left_handle_frame_get(last_seq); } return preview_frame; @@ -2310,10 +2325,10 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) if (seq == last_seq && (last_seq->flag & SELECT)) { continue; } - if (min_ii(seq->startdisp, seq->start) > v2d->cur.xmax) { + if (min_ii(SEQ_time_left_handle_frame_get(seq), seq->start) > v2d->cur.xmax) { continue; } - if (max_ii(seq->enddisp, seq->start + seq->len) < v2d->cur.xmin) { + if (max_ii(SEQ_time_right_handle_frame_get(seq), seq->start + seq->len) < v2d->cur.xmin) { continue; } if (seq->machine + 1.0f < v2d->cur.ymin) { @@ -2368,9 +2383,9 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) immUniformColor4ub(255, 255, 255, 48); immRectf(pos, - seq->startdisp, + SEQ_time_left_handle_frame_get(seq), seq->machine + SEQ_STRIP_OFSBOTTOM, - seq->enddisp, + SEQ_time_right_handle_frame_get(seq), seq->machine + SEQ_STRIP_OFSTOP); immUnbindProgram(); @@ -2597,7 +2612,8 @@ static void draw_cache_view(const bContext *C) continue; } - if (seq->startdisp > v2d->cur.xmax || seq->enddisp < v2d->cur.xmin) { + if (SEQ_time_left_handle_frame_get(seq) > v2d->cur.xmax || + SEQ_time_right_handle_frame_get(seq) < v2d->cur.xmin) { continue; } @@ -2607,7 +2623,11 @@ static void draw_cache_view(const bContext *C) if (scene->ed->cache_flag & SEQ_CACHE_VIEW_RAW) { const float bg_color[4] = {1.0f, 0.1f, 0.02f, 0.1f}; immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]); - immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top); + immRectf(pos, + SEQ_time_left_handle_frame_get(seq), + stripe_bot, + SEQ_time_right_handle_frame_get(seq), + stripe_top); } stripe_bot += stripe_ht + stripe_ofs_y; @@ -2616,7 +2636,11 @@ static void draw_cache_view(const bContext *C) if (scene->ed->cache_flag & SEQ_CACHE_VIEW_PREPROCESSED) { const float bg_color[4] = {0.1f, 0.1f, 0.75f, 0.1f}; immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]); - immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top); + immRectf(pos, + SEQ_time_left_handle_frame_get(seq), + stripe_bot, + SEQ_time_right_handle_frame_get(seq), + stripe_top); } stripe_top = seq->machine + SEQ_STRIP_OFSTOP - stripe_ofs_y; @@ -2625,7 +2649,11 @@ static void draw_cache_view(const bContext *C) if (scene->ed->cache_flag & SEQ_CACHE_VIEW_COMPOSITE) { const float bg_color[4] = {1.0f, 0.6f, 0.0f, 0.1f}; immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]); - immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top); + immRectf(pos, + SEQ_time_left_handle_frame_get(seq), + stripe_bot, + SEQ_time_right_handle_frame_get(seq), + stripe_top); } } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 08f98dfb161..75966d4f070 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -77,7 +77,6 @@ typedef struct TransSeq { int start, machine; - int startdisp, enddisp; int startofs, endofs; int anim_startofs, anim_endofs; /* int final_left, final_right; */ /* UNUSED */ @@ -345,7 +344,6 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_active_seqbase_get(ed); ListBase *channels = SEQ_channels_displayed_get(ed); Sequence *seq; int snap_frame; @@ -361,15 +359,15 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) } else { if (seq->flag & SEQ_LEFTSEL) { - SEQ_time_left_handle_frame_set(seq, snap_frame); + SEQ_time_left_handle_frame_set(scene, seq, snap_frame); } else { /* SEQ_RIGHTSEL */ - SEQ_time_right_handle_frame_set(seq, snap_frame); + SEQ_time_right_handle_frame_set(scene, seq, snap_frame); } - SEQ_transform_handle_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL); - SEQ_transform_fix_single_image_seq_offsets(seq); + SEQ_transform_handle_xlimits( + scene, seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL); + SEQ_transform_fix_single_image_seq_offsets(scene, seq); } - SEQ_time_update_sequence(scene, seqbase, seq); } } @@ -390,27 +388,22 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) if (seq->seq1 && (seq->seq1->flag & SELECT)) { if (!either_handle_selected) { - SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); + SEQ_offset_animdata(scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(seq))); } - SEQ_time_update_sequence(scene, seqbase, seq); } else if (seq->seq2 && (seq->seq2->flag & SELECT)) { if (!either_handle_selected) { - SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); + SEQ_offset_animdata(scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(seq))); } - SEQ_time_update_sequence(scene, seqbase, seq); } else if (seq->seq3 && (seq->seq3->flag & SELECT)) { if (!either_handle_selected) { - SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); + SEQ_offset_animdata(scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(seq))); } - SEQ_time_update_sequence(scene, seqbase, seq); } } } - SEQ_sort(SEQ_active_seqbase_get(ed)); - DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -477,8 +470,6 @@ static void transseq_backup(TransSeq *ts, Sequence *seq) { ts->start = seq->start; ts->machine = seq->machine; - ts->startdisp = seq->startdisp; - ts->enddisp = seq->enddisp; ts->startofs = seq->startofs; ts->endofs = seq->endofs; ts->anim_startofs = seq->anim_startofs; @@ -490,8 +481,6 @@ static void transseq_restore(TransSeq *ts, Sequence *seq) { seq->start = ts->start; seq->machine = ts->machine; - seq->startdisp = ts->startdisp; - seq->enddisp = ts->enddisp; seq->startofs = ts->startofs; seq->endofs = ts->endofs; seq->anim_startofs = ts->anim_startofs; @@ -605,22 +594,8 @@ static void sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) endframe = seq->start + seq->len; /* Compute the sequence offsets. */ - seq->endofs = endframe - seq->enddisp; - seq->startofs = seq->startdisp - seq->start; - } - else { - /* No transform data (likely effect strip). Only move start and end. */ - seq->startdisp = data->ts[i].startdisp + offset; - seq->enddisp = data->ts[i].enddisp + offset; - } - - /* Effects are only added if we they are in a meta-strip. - * In this case, dependent strips will just be transformed and - * we can skip calculating for effects. - * This way we can avoid an extra loop just for effects. */ - if (!(seq->type & SEQ_TYPE_EFFECT)) { - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); - SEQ_time_update_sequence(scene, seqbase, seq); + seq->endofs = endframe - SEQ_time_right_handle_frame_get(seq); + seq->startofs = SEQ_time_left_handle_frame_get(seq) - seq->start; } } @@ -640,12 +615,12 @@ static void sequencer_slip_apply_limits(SlipData *data, int *offset) int seq_content_end = seq_content_start + seq->len + seq->anim_startofs + seq->anim_endofs; int diff = 0; - if (seq_content_start >= seq->enddisp) { - diff = seq->enddisp - seq_content_start - 1; + if (seq_content_start >= SEQ_time_right_handle_frame_get(seq)) { + diff = SEQ_time_right_handle_frame_get(seq) - seq_content_start - 1; } - if (seq_content_end <= seq->startdisp) { - diff = seq->startdisp - seq_content_end + 1; + if (seq_content_end <= SEQ_time_left_handle_frame_get(seq)) { + diff = SEQ_time_left_handle_frame_get(seq) - seq_content_end + 1; } *offset += diff; } @@ -791,8 +766,6 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even for (int i = 0; i < data->num_seq; i++) { Sequence *seq = data->seq_array[i]; SEQ_add_reload_new_file(bmain, scene, seq, false); - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); - SEQ_time_update_sequence(scene, seqbase, seq); } MEM_freeN(data->seq_array); @@ -1288,7 +1261,6 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op) last_seq->seq3 = seq3; int old_start = last_seq->start; - SEQ_time_update_recursive(scene, last_seq); SEQ_relations_invalidate_cache_preprocessed(scene, last_seq); SEQ_offset_animdata(scene, last_seq, (last_seq->start - old_start)); @@ -1446,13 +1418,15 @@ static int sequencer_split_exec(bContext *C, wmOperator *op) if (ignore_selection) { if (use_cursor_position) { LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { - if (seq->enddisp == split_frame && seq->machine == split_channel) { + if (SEQ_time_right_handle_frame_get(seq) == split_frame && + seq->machine == split_channel) { seq_selected = seq->flag & SEQ_ALLSEL; } } if (!seq_selected) { LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { - if (seq->startdisp == split_frame && seq->machine == split_channel) { + if (SEQ_time_left_handle_frame_get(seq) == split_frame && + seq->machine == split_channel) { seq->flag &= ~SEQ_ALLSEL; } } @@ -1463,20 +1437,18 @@ static int sequencer_split_exec(bContext *C, wmOperator *op) if (split_side != SEQ_SIDE_BOTH) { LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (split_side == SEQ_SIDE_LEFT) { - if (seq->startdisp >= split_frame) { + if (SEQ_time_left_handle_frame_get(seq) >= split_frame) { seq->flag &= ~SEQ_ALLSEL; } } else { - if (seq->enddisp <= split_frame) { + if (SEQ_time_right_handle_frame_get(seq) <= split_frame) { seq->flag &= ~SEQ_ALLSEL; } } } } } - - SEQ_sort(SEQ_active_seqbase_get(ed)); } if (changed) { WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1791,8 +1763,6 @@ static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) /* Update lengths, etc. */ seq = ed->seqbasep->first; while (seq) { - ListBase *seqbase = SEQ_active_seqbase_get(ed); - SEQ_time_update_sequence(scene, seqbase, seq); SEQ_relations_invalidate_cache_preprocessed(scene, seq); seq = seq->next; } @@ -1883,8 +1853,6 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) BLI_strncpy(se_new->name, se->name, sizeof(se_new->name)); strip_new->stripdata = se_new; - SEQ_time_update_sequence(scene, seqbase, seq_new); - if (step > 1) { seq_new->flag &= ~SEQ_OVERLAP; if (SEQ_transform_test_overlap(seqbase, seq_new)) { @@ -1908,9 +1876,6 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) } SEQ_edit_remove_flagged_sequences(scene, seqbase); - - SEQ_sort(seqbase); - WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -2020,8 +1985,8 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) BLI_addtail(&seqm->seqbase, seq); SEQ_relations_invalidate_cache_preprocessed(scene, seq); channel_max = max_ii(seq->machine, channel_max); - meta_start_frame = min_ii(seq->startdisp, meta_start_frame); - meta_end_frame = max_ii(seq->enddisp, meta_end_frame); + meta_start_frame = min_ii(SEQ_time_left_handle_frame_get(seq), meta_start_frame); + meta_end_frame = max_ii(SEQ_time_right_handle_frame_get(seq), meta_end_frame); } } @@ -2030,7 +1995,6 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) SEQ_sequence_base_unique_name_recursive(scene, &ed->seqbase, seqm); seqm->start = meta_start_frame; seqm->len = meta_end_frame - meta_start_frame; - SEQ_time_update_sequence(scene, active_seqbase, seqm); SEQ_select_active_set(scene, seqm); if (SEQ_transform_test_overlap(active_seqbase, seqm)) { SEQ_transform_seqbase_shuffle(active_seqbase, seqm, scene); @@ -2098,7 +2062,6 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) } } - SEQ_sort(active_seqbase); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -2204,19 +2167,18 @@ static const EnumPropertyItem prop_side_lr_types[] = { static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb) { - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); - int gap = seqb->startdisp - seqa->enddisp; + int gap = SEQ_time_left_handle_frame_get(seqb) - SEQ_time_right_handle_frame_get(seqa); int seq_a_start; int seq_b_start; - seq_b_start = (seqb->start - seqb->startdisp) + seqa->startdisp; + seq_b_start = (seqb->start - SEQ_time_left_handle_frame_get(seqb)) + + SEQ_time_left_handle_frame_get(seqa); SEQ_transform_translate_sequence(scene, seqb, seq_b_start - seqb->start); - SEQ_time_update_sequence(scene, seqbase, seqb); SEQ_relations_invalidate_cache_preprocessed(scene, seqb); - seq_a_start = (seqa->start - seqa->startdisp) + seqb->enddisp + gap; + seq_a_start = (seqa->start - SEQ_time_left_handle_frame_get(seqa)) + + SEQ_time_right_handle_frame_get(seqb) + gap; SEQ_transform_translate_sequence(scene, seqa, seq_a_start - seqa->start); - SEQ_time_update_sequence(scene, seqbase, seqa); SEQ_relations_invalidate_cache_preprocessed(scene, seqa); } @@ -2241,13 +2203,13 @@ static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, i switch (lr) { case SEQ_SIDE_LEFT: - if (seq->enddisp <= test->startdisp) { - dist = test->enddisp - seq->startdisp; + if (SEQ_time_right_handle_frame_get(seq) <= SEQ_time_left_handle_frame_get(test)) { + dist = SEQ_time_right_handle_frame_get(test) - SEQ_time_left_handle_frame_get(seq); } break; case SEQ_SIDE_RIGHT: - if (seq->startdisp >= test->enddisp) { - dist = seq->startdisp - test->enddisp; + if (SEQ_time_left_handle_frame_get(seq) >= SEQ_time_right_handle_frame_get(test)) { + dist = SEQ_time_left_handle_frame_get(seq) - SEQ_time_right_handle_frame_get(test); } break; } @@ -2307,14 +2269,6 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op) break; } - /* XXX: Should be a generic function. */ - for (iseq = seqbase->first; iseq; iseq = iseq->next) { - if ((iseq->type & SEQ_TYPE_EFFECT) && - (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { - SEQ_time_update_sequence(scene, seqbase, iseq); - } - } - /* Do this in a new loop since both effects need to be calculated first. */ for (iseq = seqbase->first; iseq; iseq = iseq->next) { if ((iseq->type & SEQ_TYPE_EFFECT) && @@ -2326,10 +2280,7 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op) } } - SEQ_sort(SEQ_active_seqbase_get(ed)); - WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); - return OPERATOR_FINISHED; } @@ -2576,8 +2527,8 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) else { int min_seq_startdisp = INT_MAX; LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) { - if (seq->startdisp < min_seq_startdisp) { - min_seq_startdisp = seq->startdisp; + if (SEQ_time_left_handle_frame_get(seq) < min_seq_startdisp) { + min_seq_startdisp = SEQ_time_left_handle_frame_get(seq); } } /* Paste strips relative to the current-frame. */ @@ -2608,13 +2559,17 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) * in the new list. */ BLI_movelisttolist(ed->seqbasep, &nseqbase); + /* Make sure, that pasted strips have unique names. This has to be done immediately after adding + * strips to seqbase, for lookup cache to work correctly. */ + for (iseq = iseq_first; iseq; iseq = iseq->next) { + SEQ_ensure_unique_name(iseq, scene); + } + for (iseq = iseq_first; iseq; iseq = iseq->next) { if (SEQ_clipboard_pasted_seq_was_active(iseq)) { SEQ_select_active_set(scene, iseq); } - /* Make sure, that pasted strips have unique names. */ - SEQ_ensure_unique_name(iseq, scene); /* Translate after name has been changed, otherwise this will affect animdata of original * strip. */ SEQ_transform_translate_sequence(scene, iseq, ofs); @@ -2692,10 +2647,6 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op) seq_act->scene_sound = NULL; seq_other->scene_sound = NULL; - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); - SEQ_time_update_sequence(scene, seqbase, seq_act); - SEQ_time_update_sequence(scene, seqbase, seq_other); - if (seq_act->sound) { BKE_sound_add_scene_sound_defaults(scene, seq_act); } @@ -2938,9 +2889,6 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op) /* Correct start/end frames so we don't move. * Important not to set seq->len = len; allow the function to handle it. */ SEQ_add_reload_new_file(bmain, scene, seq, true); - - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); - SEQ_time_update_sequence(scene, seqbase, seq); } else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { bSound *sound = seq->sound; @@ -3160,7 +3108,7 @@ static bool seq_get_text_strip_cb(Sequence *seq, void *user_data) ListBase *channels = SEQ_channels_displayed_get(ed); /* Only text strips that are not muted and don't end with negative frame. */ if ((seq->type == SEQ_TYPE_TEXT) && !SEQ_render_is_muted(channels, seq) && - (seq->enddisp > cd->scene->r.sfra)) { + (SEQ_time_right_handle_frame_get(seq) > cd->scene->r.sfra)) { BLI_addtail(cd->text_seq, MEM_dupallocN(seq)); } return true; @@ -3218,16 +3166,17 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op) char timecode_str_end[32]; /* Write time-code relative to start frame of scene. Don't allow negative time-codes. */ - BLI_timecode_string_from_time(timecode_str_start, - sizeof(timecode_str_start), - -2, - FRA2TIME(max_ii(seq->startdisp - scene->r.sfra, 0)), - FPS, - USER_TIMECODE_SUBRIP); + BLI_timecode_string_from_time( + timecode_str_start, + sizeof(timecode_str_start), + -2, + FRA2TIME(max_ii(SEQ_time_left_handle_frame_get(seq) - scene->r.sfra, 0)), + FPS, + USER_TIMECODE_SUBRIP); BLI_timecode_string_from_time(timecode_str_end, sizeof(timecode_str_end), -2, - FRA2TIME(seq->enddisp - scene->r.sfra), + FRA2TIME(SEQ_time_right_handle_frame_get(seq) - scene->r.sfra), FPS, USER_TIMECODE_SUBRIP); @@ -3295,8 +3244,8 @@ static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op) for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT) { selected = true; - sfra = min_ii(sfra, seq->startdisp); - efra = max_ii(efra, seq->enddisp - 1); + sfra = min_ii(sfra, SEQ_time_left_handle_frame_get(seq)); + efra = max_ii(efra, SEQ_time_right_handle_frame_get(seq) - 1); } } diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 074be0fd120..f237fbc0a12 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -116,13 +116,13 @@ static void select_active_side(ListBase *seqbase, int sel_side, int channel, int if (channel == seq->machine) { switch (sel_side) { case SEQ_SIDE_LEFT: - if (frame > (seq->startdisp)) { + if (frame > (SEQ_time_left_handle_frame_get(seq))) { seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); seq->flag |= SELECT; } break; case SEQ_SIDE_RIGHT: - if (frame < (seq->startdisp)) { + if (frame < (SEQ_time_left_handle_frame_get(seq))) { seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); seq->flag |= SELECT; } @@ -152,13 +152,13 @@ static void select_active_side_range(ListBase *seqbase, } switch (sel_side) { case SEQ_SIDE_LEFT: - if (frame > (seq->startdisp)) { + if (frame > (SEQ_time_left_handle_frame_get(seq))) { seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); seq->flag |= SELECT; } break; case SEQ_SIDE_RIGHT: - if (frame < (seq->startdisp)) { + if (frame < (SEQ_time_left_handle_frame_get(seq))) { seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); seq->flag |= SELECT; } @@ -179,8 +179,8 @@ static void select_linked_time(ListBase *seqbase, Sequence *seq_link) for (seq = seqbase->first; seq; seq = seq->next) { if (seq_link->machine != seq->machine) { - int left_match = (seq->startdisp == seq_link->startdisp) ? 1 : 0; - int right_match = (seq->enddisp == seq_link->enddisp) ? 1 : 0; + int left_match = (SEQ_time_left_handle_frame_get(seq) == seq_link->startdisp) ? 1 : 0; + int right_match = (SEQ_time_right_handle_frame_get(seq) == seq_link->enddisp) ? 1 : 0; if (left_match && right_match) { /* Direct match, copy the selection settings. */ @@ -247,8 +247,8 @@ void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool desel void seq_rectf(Sequence *seq, rctf *rect) { - rect->xmin = seq->startdisp; - rect->xmax = seq->enddisp; + rect->xmin = SEQ_time_left_handle_frame_get(seq); + rect->xmax = SEQ_time_right_handle_frame_get(seq); rect->ymin = seq->machine + SEQ_STRIP_OFSBOTTOM; rect->ymax = seq->machine + SEQ_STRIP_OFSTOP; } @@ -273,12 +273,12 @@ Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int se (sel == 0 && (seq->flag & SELECT) == 0))) { switch (lr) { case SEQ_SIDE_LEFT: - if (test->startdisp == (seq->enddisp)) { + if (SEQ_time_left_handle_frame_get(test) == (SEQ_time_right_handle_frame_get(seq))) { return seq; } break; case SEQ_SIDE_RIGHT: - if (test->enddisp == (seq->startdisp)) { + if (SEQ_time_right_handle_frame_get(test) == (SEQ_time_left_handle_frame_get(seq))) { return seq; } break; @@ -311,13 +311,18 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[ while (seq) { if (seq->machine == (int)y) { /* Check for both normal strips, and strips that have been flipped horizontally. */ - if (((seq->startdisp < seq->enddisp) && (seq->startdisp <= x && seq->enddisp >= x)) || - ((seq->startdisp > seq->enddisp) && (seq->startdisp >= x && seq->enddisp <= x))) { + if (((SEQ_time_left_handle_frame_get(seq) < SEQ_time_right_handle_frame_get(seq)) && + (SEQ_time_left_handle_frame_get(seq) <= x && + SEQ_time_right_handle_frame_get(seq) >= x)) || + ((SEQ_time_left_handle_frame_get(seq) > SEQ_time_right_handle_frame_get(seq)) && + (SEQ_time_left_handle_frame_get(seq) >= x && + SEQ_time_right_handle_frame_get(seq) <= x))) { if (SEQ_transform_sequence_can_be_translated(seq)) { /* Clamp handles to defined size in pixel space. */ handsize = 2.0f * sequence_handle_size_get_clamped(seq, pixelx); - displen = (float)abs(seq->startdisp - seq->enddisp); + displen = (float)abs(SEQ_time_left_handle_frame_get(seq) - + SEQ_time_right_handle_frame_get(seq)); /* Don't even try to grab the handles of small strips. */ if (displen / pixelx > 16) { @@ -332,10 +337,10 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[ CLAMP(handsize, 7 * pixelx, 30 * pixelx); } - if (handsize + seq->startdisp >= x) { + if (handsize + SEQ_time_left_handle_frame_get(seq) >= x) { *hand = SEQ_SIDE_LEFT; } - else if (-handsize + seq->enddisp <= x) { + else if (-handsize + SEQ_time_right_handle_frame_get(seq) <= x) { *hand = SEQ_SIDE_RIGHT; } } @@ -578,8 +583,8 @@ static void sequencer_select_side_of_frame(const bContext *C, const float x = UI_view2d_region_to_view_x(v2d, mval[0]); LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) { - if (((x < CFRA) && (seq_iter->enddisp <= CFRA)) || - ((x >= CFRA) && (seq_iter->startdisp >= CFRA))) { + if (((x < CFRA) && (SEQ_time_right_handle_frame_get(seq_iter) <= CFRA)) || + ((x >= CFRA) && (SEQ_time_left_handle_frame_get(seq_iter) >= CFRA))) { /* Select left or right. */ seq_iter->flag |= SELECT; recurs_sel_seq(seq_iter); @@ -634,7 +639,8 @@ static void sequencer_select_linked_handle(const bContext *C, case SEQ_SIDE_LEFT: if ((seq->flag & SEQ_LEFTSEL) && (neighbor->flag & SEQ_RIGHTSEL)) { seq->flag |= SELECT; - select_active_side(ed->seqbasep, SEQ_SIDE_LEFT, seq->machine, seq->startdisp); + select_active_side( + ed->seqbasep, SEQ_SIDE_LEFT, seq->machine, SEQ_time_left_handle_frame_get(seq)); } else { seq->flag |= SELECT; @@ -647,7 +653,8 @@ static void sequencer_select_linked_handle(const bContext *C, case SEQ_SIDE_RIGHT: if ((seq->flag & SEQ_RIGHTSEL) && (neighbor->flag & SEQ_LEFTSEL)) { seq->flag |= SELECT; - select_active_side(ed->seqbasep, SEQ_SIDE_RIGHT, seq->machine, seq->startdisp); + select_active_side( + ed->seqbasep, SEQ_SIDE_RIGHT, seq->machine, SEQ_time_left_handle_frame_get(seq)); } else { seq->flag |= SELECT; @@ -661,7 +668,8 @@ static void sequencer_select_linked_handle(const bContext *C, } else { - select_active_side(ed->seqbasep, sel_side, seq->machine, seq->startdisp); + select_active_side( + ed->seqbasep, sel_side, seq->machine, SEQ_time_left_handle_frame_get(seq)); } } } @@ -1428,10 +1436,10 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) bool test = false; switch (side) { case -1: - test = (timeline_frame >= seq->enddisp); + test = (timeline_frame >= SEQ_time_right_handle_frame_get(seq)); break; case 1: - test = (timeline_frame <= seq->startdisp); + test = (timeline_frame <= SEQ_time_left_handle_frame_get(seq)); break; case 2: test = SEQ_time_strip_intersects_frame(seq, timeline_frame); @@ -1505,10 +1513,10 @@ static int sequencer_select_side_exec(bContext *C, wmOperator *op) if (seq->flag & SELECT) { selected = true; if (sel_side == SEQ_SIDE_LEFT) { - *frame_limit_p = max_ii(*frame_limit_p, seq->startdisp); + *frame_limit_p = max_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(seq)); } else { - *frame_limit_p = min_ii(*frame_limit_p, seq->startdisp); + *frame_limit_p = min_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(seq)); } } } @@ -1648,7 +1656,7 @@ static int sequencer_box_select_exec(bContext *C, wmOperator *op) float handsize = sequence_handle_size_get_clamped(seq, pixelx); /* Right handle. */ - if (rectf.xmax > (seq->enddisp - handsize)) { + if (rectf.xmax > (SEQ_time_right_handle_frame_get(seq) - handsize)) { if (select) { seq->flag |= SELECT | SEQ_RIGHTSEL; } @@ -1661,7 +1669,7 @@ static int sequencer_box_select_exec(bContext *C, wmOperator *op) } } /* Left handle. */ - if (rectf.xmin < (seq->startdisp + handsize)) { + if (rectf.xmin < (SEQ_time_left_handle_frame_get(seq) + handsize)) { if (select) { seq->flag |= SELECT | SEQ_LEFTSEL; } @@ -1953,7 +1961,8 @@ static bool select_grouped_time_overlap(SeqCollection *strips, Sequence *seq; SEQ_ITERATOR_FOREACH (seq, strips) { - if (seq->startdisp < actseq->enddisp && seq->enddisp > actseq->startdisp) { + if (SEQ_time_left_handle_frame_get(seq) < SEQ_time_right_handle_frame_get(actseq) && + SEQ_time_right_handle_frame_get(seq) > SEQ_time_left_handle_frame_get(actseq)) { seq->flag |= SELECT; changed = true; } @@ -1971,8 +1980,10 @@ static void query_lower_channel_strips(Sequence *seq_reference, if (seq_test->machine > seq_reference->machine) { continue; /* Not lower channel. */ } - if (seq_test->enddisp <= seq_reference->startdisp || - seq_test->startdisp >= seq_reference->enddisp) { + if (SEQ_time_right_handle_frame_get(seq_test) <= + SEQ_time_left_handle_frame_get(seq_reference) || + SEQ_time_left_handle_frame_get(seq_test) >= + SEQ_time_right_handle_frame_get(seq_reference)) { continue; /* Not intersecting in time. */ } SEQ_collection_append_strip(seq_test, collection); diff --git a/source/blender/editors/space_sequencer/sequencer_thumbnails.c b/source/blender/editors/space_sequencer/sequencer_thumbnails.c index eab17d876f3..984d3b1f374 100644 --- a/source/blender/editors/space_sequencer/sequencer_thumbnails.c +++ b/source/blender/editors/space_sequencer/sequencer_thumbnails.c @@ -74,10 +74,10 @@ static bool check_seq_need_thumbnails(Sequence *seq, rctf *view_area) if (!ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE)) { return false; } - if (min_ii(seq->startdisp, seq->start) > view_area->xmax) { + if (min_ii(SEQ_time_left_handle_frame_get(seq), seq->start) > view_area->xmax) { return false; } - if (max_ii(seq->enddisp, seq->start + seq->len) < view_area->xmin) { + if (max_ii(SEQ_time_right_handle_frame_get(seq), seq->start + seq->len) < view_area->xmin) { return false; } if (seq->machine + 1.0f < view_area->ymin) { @@ -206,7 +206,7 @@ static GHash *sequencer_thumbnail_ghash_init(const bContext *C, View2D *v2d, Edi else { if (val_need_update != NULL) { val_need_update->seq_dupli->start = seq->start; - val_need_update->seq_dupli->startdisp = seq->startdisp; + val_need_update->seq_dupli->startdisp = SEQ_time_left_handle_frame_get(seq); } } } @@ -363,15 +363,16 @@ static int sequencer_thumbnail_closest_previous_frame_get(int timeline_frame, static int sequencer_thumbnail_closest_guaranteed_frame_get(Sequence *seq, int timeline_frame) { - if (timeline_frame <= seq->startdisp) { - return seq->startdisp; + if (timeline_frame <= SEQ_time_left_handle_frame_get(seq)) { + return SEQ_time_left_handle_frame_get(seq); } /* Set of "guaranteed" thumbnails. */ - const int frame_index = timeline_frame - seq->startdisp; + const int frame_index = timeline_frame - SEQ_time_left_handle_frame_get(seq); const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(seq); const int relative_base_frame = round_fl_to_int((frame_index / (float)frame_step)) * frame_step; - const int nearest_guaranted_absolute_frame = relative_base_frame + seq->startdisp; + const int nearest_guaranted_absolute_frame = relative_base_frame + + SEQ_time_left_handle_frame_get(seq); return nearest_guaranted_absolute_frame; } @@ -444,10 +445,11 @@ void draw_seq_strip_thumbnail(View2D *v2d, float thumb_y_end = y1 + thumb_height; float cut_off = 0; - float upper_thumb_bound = SEQ_time_has_right_still_frames(seq) ? (seq->start + seq->len) : - seq->enddisp; + float upper_thumb_bound = SEQ_time_has_right_still_frames(seq) ? + (seq->start + seq->len) : + SEQ_time_right_handle_frame_get(seq); if (seq->type == SEQ_TYPE_IMAGE) { - upper_thumb_bound = seq->enddisp; + upper_thumb_bound = SEQ_time_right_handle_frame_get(seq); } float timeline_frame = SEQ_render_thumbnail_first_frame_get(seq, thumb_width, &v2d->cur); @@ -473,8 +475,8 @@ void draw_seq_strip_thumbnail(View2D *v2d, } /* Set the clipping bound to show the left handle moving over thumbs and not shift thumbs. */ - if (IN_RANGE_INCL(seq->startdisp, timeline_frame, thumb_x_end)) { - cut_off = seq->startdisp - timeline_frame; + if (IN_RANGE_INCL(SEQ_time_left_handle_frame_get(seq), timeline_frame, thumb_x_end)) { + cut_off = SEQ_time_left_handle_frame_get(seq) - timeline_frame; clipped = true; } diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index 93641375d42..857ca6d989b 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -306,8 +306,8 @@ static void seq_view_collection_rect_timeline(Scene *scene, SeqCollection *strip int xmargin = FPS; SEQ_ITERATOR_FOREACH (seq, strips) { - xmin = min_ii(xmin, seq->startdisp); - xmax = max_ii(xmax, seq->enddisp); + xmin = min_ii(xmin, SEQ_time_left_handle_frame_get(seq)); + xmax = max_ii(xmax, SEQ_time_right_handle_frame_get(seq)); ymin = min_ii(ymin, seq->machine); ymax = max_ii(ymax, seq->machine); diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc index a498e5e99cf..dd3aac1eae9 100644 --- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc +++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc @@ -302,6 +302,7 @@ static float get_default_column_width(const ColumnValues &values) switch (values.type()) { case SPREADSHEET_VALUE_TYPE_BOOL: return 2.0f; + case SPREADSHEET_VALUE_TYPE_INT8: case SPREADSHEET_VALUE_TYPE_INT32: return float_width; case SPREADSHEET_VALUE_TYPE_FLOAT: diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc index a29aa1fd026..46e98acb8e8 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc @@ -23,6 +23,9 @@ eSpreadsheetColumnValueType cpp_type_to_column_type(const CPPType &type) if (type.is<bool>()) { return SPREADSHEET_VALUE_TYPE_BOOL; } + if (type.is<int8_t>()) { + return SPREADSHEET_VALUE_TYPE_INT8; + } if (type.is<int>()) { return SPREADSHEET_VALUE_TYPE_INT32; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index ac15b77fde0..f5315b616d0 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -512,7 +512,7 @@ class GeometryComponentCacheValue : public SpreadsheetCache::Value { public: /* Stores the result of fields evaluated on a geometry component. Without this, fields would have * to be reevaluated on every redraw. */ - Map<std::pair<AttributeDomain, GField>, GArray<>> arrays; + Map<std::pair<eAttrDomain, GField>, GArray<>> arrays; }; static void add_fields_as_extra_columns(SpaceSpreadsheet *sspreadsheet, @@ -526,7 +526,7 @@ static void add_fields_as_extra_columns(SpaceSpreadsheet *sspreadsheet, sspreadsheet->runtime->cache.lookup_or_add<GeometryComponentCacheValue>( std::make_unique<GeometryComponentCacheKey>(component)); - const AttributeDomain domain = (AttributeDomain)sspreadsheet->attribute_domain; + const eAttrDomain domain = (eAttrDomain)sspreadsheet->attribute_domain; const int domain_num = component.attribute_domain_num(domain); for (const auto item : fields_to_show.items()) { StringRef name = item.key; @@ -550,7 +550,7 @@ static void add_fields_as_extra_columns(SpaceSpreadsheet *sspreadsheet, std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object *object_eval) { SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); - const AttributeDomain domain = (AttributeDomain)sspreadsheet->attribute_domain; + const eAttrDomain domain = (eAttrDomain)sspreadsheet->attribute_domain; const GeometryComponentType component_type = get_display_component_type(C, object_eval); GeometrySet geometry_set = spreadsheet_get_display_geometry_set(sspreadsheet, object_eval); diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh index 8b281e5a558..04b4f6d8d06 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh @@ -40,7 +40,7 @@ class GeometryDataSource : public DataSource { Object *object_eval_; const GeometrySet geometry_set_; const GeometryComponent *component_; - AttributeDomain domain_; + eAttrDomain domain_; ExtraColumns extra_columns_; /* Some data is computed on the fly only when it is requested. Computing it does not change the @@ -53,7 +53,7 @@ class GeometryDataSource : public DataSource { GeometryDataSource(Object *object_eval, GeometrySet geometry_set, const GeometryComponentType component_type, - const AttributeDomain domain, + const eAttrDomain domain, ExtraColumns extra_columns) : object_eval_(object_eval), geometry_set_(std::move(geometry_set)), diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc index 724d0783707..ee22f4173ab 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc @@ -27,7 +27,7 @@ class GeometryDataSetTreeView; class GeometryDataSetTreeViewItem : public ui::AbstractTreeViewItem { GeometryComponentType component_type_; - std::optional<AttributeDomain> domain_; + std::optional<eAttrDomain> domain_; BIFIconID icon_; public: @@ -35,7 +35,7 @@ class GeometryDataSetTreeViewItem : public ui::AbstractTreeViewItem { StringRef label, BIFIconID icon); GeometryDataSetTreeViewItem(GeometryComponentType component_type, - AttributeDomain domain, + eAttrDomain domain, StringRef label, BIFIconID icon); @@ -113,7 +113,7 @@ GeometryDataSetTreeViewItem::GeometryDataSetTreeViewItem(GeometryComponentType c this->set_collapsed(false); } GeometryDataSetTreeViewItem::GeometryDataSetTreeViewItem(GeometryComponentType component_type, - AttributeDomain domain, + eAttrDomain domain, StringRef label, BIFIconID icon) : component_type_(component_type), domain_(domain), icon_(icon) diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc b/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc index d76bbbf3be6..166c5de9fc3 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc @@ -84,7 +84,7 @@ static int select_component_domain_invoke(bContext *C, { GeometryComponentType component_type = static_cast<GeometryComponentType>( RNA_int_get(op->ptr, "component_type")); - AttributeDomain attribute_domain = static_cast<AttributeDomain>( + eAttrDomain attribute_domain = static_cast<eAttrDomain>( RNA_int_get(op->ptr, "attribute_domain_type")); SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc index 91ce5c2f6ec..e1ff4b59b14 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc @@ -71,6 +71,35 @@ static void apply_row_filter(const SpreadsheetRowFilter &row_filter, } } } + else if (column_data.type().is<int8_t>()) { + const int value = row_filter.value_int; + switch (row_filter.operation) { + case SPREADSHEET_ROW_FILTER_EQUAL: { + apply_filter_operation( + column_data.typed<int8_t>(), + [&](const int cell) { return cell == value; }, + prev_mask, + new_indices); + break; + } + case SPREADSHEET_ROW_FILTER_GREATER: { + apply_filter_operation( + column_data.typed<int8_t>(), + [value](const int cell) { return cell > value; }, + prev_mask, + new_indices); + break; + } + case SPREADSHEET_ROW_FILTER_LESS: { + apply_filter_operation( + column_data.typed<int8_t>(), + [&](const int cell) { return cell < value; }, + prev_mask, + new_indices); + break; + } + } + } else if (column_data.type().is<int>()) { const int value = row_filter.value_int; switch (row_filter.operation) { diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc index 7c1ac024c12..d42a371c666 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc @@ -63,6 +63,7 @@ static std::string value_string(const SpreadsheetRowFilter &row_filter, const eSpreadsheetColumnValueType data_type) { switch (data_type) { + case SPREADSHEET_VALUE_TYPE_INT8: case SPREADSHEET_VALUE_TYPE_INT32: return std::to_string(row_filter.value_int); case SPREADSHEET_VALUE_TYPE_FLOAT: { @@ -200,6 +201,10 @@ static void spreadsheet_filter_panel_draw(const bContext *C, Panel *panel) } switch (static_cast<eSpreadsheetColumnValueType>(column->data_type)) { + case SPREADSHEET_VALUE_TYPE_INT8: + uiItemR(layout, filter_ptr, "operation", 0, nullptr, ICON_NONE); + uiItemR(layout, filter_ptr, "value_int8", 0, IFACE_("Value"), ICON_NONE); + break; case SPREADSHEET_VALUE_TYPE_INT32: uiItemR(layout, filter_ptr, "operation", 0, nullptr, ICON_NONE); uiItemR(layout, filter_ptr, "value_int", 0, IFACE_("Value"), ICON_NONE); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 9267ef7407a..a837102226b 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -2886,6 +2886,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op) struct SelectPick_Params params = {0}; ED_select_pick_params_from_operator(op->ptr, ¶ms); + const bool vert_without_handles = RNA_boolean_get(op->ptr, "vert_without_handles"); bool center = RNA_boolean_get(op->ptr, "center"); bool enumerate = RNA_boolean_get(op->ptr, "enumerate"); /* Only force object select for edit-mode to support vertex parenting, @@ -2940,7 +2941,8 @@ static int view3d_select_exec(bContext *C, wmOperator *op) changed = ED_lattice_select_pick(C, mval, ¶ms); } else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) { - changed = ED_curve_editnurb_select_pick(C, mval, ED_view3d_select_dist_px(), ¶ms); + changed = ED_curve_editnurb_select_pick( + C, mval, ED_view3d_select_dist_px(), vert_without_handles, ¶ms); } else if (obedit->type == OB_MBALL) { changed = ED_mball_select_pick(C, mval, ¶ms); @@ -3017,6 +3019,15 @@ void VIEW3D_OT_select(wmOperatorType *ot) prop = RNA_def_boolean(ot->srna, "object", 0, "Object", "Use object selection (edit mode only)"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); + /* Needed for select-through to usefully drag handles, see: T98254. + * NOTE: this option may be removed and become default behavior, see design task: T98552. */ + prop = RNA_def_boolean(ot->srna, + "vert_without_handles", + 0, + "Control Point Without Handles", + "Only select the curve control point, not it's handles"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_int_vector(ot->srna, "location", 2, diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index a7e2f616c9e..f8793e2a747 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1786,13 +1786,6 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve t->launch_event = event ? WM_userdef_event_type_from_keymap_type(event->type) : -1; t->is_launch_event_drag = event ? (event->val == KM_CLICK_DRAG) : false; - /* XXX Remove this when wm_operator_call_internal doesn't use window->eventstate - * (which can have type = 0) */ - /* For gizmo only, so assume LEFTMOUSE. */ - if (t->launch_event == 0) { - t->launch_event = LEFTMOUSE; - } - unit_m3(t->spacemtx); initTransInfo(C, t, op, event); diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c index 3735ff0727c..68f04aab969 100644 --- a/source/blender/editors/transform/transform_convert_sequencer.c +++ b/source/blender/editors/transform/transform_convert_sequencer.c @@ -278,8 +278,6 @@ static void seq_transform_cancel(TransInfo *t, SeqCollection *transformed_strips if (SEQ_transform_test_overlap(seqbase, seq)) { SEQ_transform_seqbase_shuffle(seqbase, seq, t->scene); } - - SEQ_time_update_sequence(t->scene, seqbase, seq); } } @@ -313,43 +311,19 @@ static SeqCollection *query_right_side_strips(ListBase *seqbase, SeqCollection * { Sequence *seq; SEQ_ITERATOR_FOREACH (seq, transformed_strips) { - minframe = min_ii(minframe, seq->startdisp); + minframe = min_ii(minframe, SEQ_time_left_handle_frame_get(seq)); } } SeqCollection *collection = SEQ_collection_create(__func__); LISTBASE_FOREACH (Sequence *, seq, seqbase) { - if ((seq->flag & SELECT) == 0 && seq->startdisp >= minframe) { + if ((seq->flag & SELECT) == 0 && SEQ_time_left_handle_frame_get(seq) >= minframe) { SEQ_collection_append_strip(seq, collection); } } return collection; } -static void seq_transform_update_effects(Scene *scene, - ListBase *seqbasep, - SeqCollection *collection) -{ - Sequence *seq; - SEQ_ITERATOR_FOREACH (seq, collection) { - if ((seq->type & SEQ_TYPE_EFFECT) && (seq->seq1 || seq->seq2 || seq->seq3)) { - SEQ_time_update_sequence(scene, seqbasep, seq); - } - } -} - -/* Check if effect strips with input are transformed. */ -static bool seq_transform_check_strip_effects(SeqCollection *transformed_strips) -{ - Sequence *seq; - SEQ_ITERATOR_FOREACH (seq, transformed_strips) { - if ((seq->type & SEQ_TYPE_EFFECT) && (seq->seq1 || seq->seq2 || seq->seq3)) { - return true; - } - } - return false; -} - static ListBase *seqbase_active_get(const TransInfo *t) { Editing *ed = SEQ_editing_get(t->scene); @@ -388,7 +362,6 @@ static void seq_transform_handle_expand_to_fit(Scene *scene, * SEQ_transform_handle_overlap. */ SEQ_transform_seqbase_shuffle_time( right_side_strips, seqbasep, scene, markers, use_sync_markers); - seq_transform_update_effects(scene, seqbasep, right_side_strips); SEQ_collection_free(right_side_strips); } @@ -434,16 +407,20 @@ typedef enum eOvelapDescrition { static eOvelapDescrition overlap_description_get(const Sequence *transformed, const Sequence *target) { - if (transformed->startdisp <= target->startdisp && transformed->enddisp >= target->enddisp) { + if (SEQ_time_left_handle_frame_get(transformed) <= SEQ_time_left_handle_frame_get(target) && + SEQ_time_right_handle_frame_get(transformed) >= SEQ_time_right_handle_frame_get(target)) { return STRIP_OVERLAP_IS_FULL; } - if (transformed->startdisp > target->startdisp && transformed->enddisp < target->enddisp) { + if (SEQ_time_left_handle_frame_get(transformed) > SEQ_time_left_handle_frame_get(target) && + SEQ_time_right_handle_frame_get(transformed) < SEQ_time_right_handle_frame_get(target)) { return STRIP_OVERLAP_IS_INSIDE; } - if (transformed->startdisp <= target->startdisp && target->startdisp <= transformed->enddisp) { + if (SEQ_time_left_handle_frame_get(transformed) <= SEQ_time_left_handle_frame_get(target) && + SEQ_time_left_handle_frame_get(target) <= SEQ_time_right_handle_frame_get(transformed)) { return STRIP_OVERLAP_LEFT_SIDE; } - if (transformed->startdisp <= target->enddisp && target->enddisp <= transformed->enddisp) { + if (SEQ_time_left_handle_frame_get(transformed) <= SEQ_time_right_handle_frame_get(target) && + SEQ_time_right_handle_frame_get(target) <= SEQ_time_right_handle_frame_get(transformed)) { return STRIP_OVERLAP_RIGHT_SIDE; } return STRIP_OVERLAP_NONE; @@ -459,10 +436,20 @@ static void seq_transform_handle_overwrite_split(Scene *scene, * NULL here. */ Main *bmain = NULL; - Sequence *split_strip = SEQ_edit_strip_split( - bmain, scene, seqbasep, target, transformed->startdisp, SEQ_SPLIT_SOFT, NULL); - SEQ_edit_strip_split( - bmain, scene, seqbasep, split_strip, transformed->enddisp, SEQ_SPLIT_SOFT, NULL); + Sequence *split_strip = SEQ_edit_strip_split(bmain, + scene, + seqbasep, + target, + SEQ_time_left_handle_frame_get(transformed), + SEQ_SPLIT_SOFT, + NULL); + SEQ_edit_strip_split(bmain, + scene, + seqbasep, + split_strip, + SEQ_time_right_handle_frame_get(transformed), + SEQ_SPLIT_SOFT, + NULL); SEQ_edit_flag_for_removal(scene, seqbasep, split_strip); SEQ_edit_remove_flagged_sequences(scene, seqbasep); } @@ -489,14 +476,12 @@ static void seq_transform_handle_overwrite_trim(Scene *scene, continue; } if (overlap == STRIP_OVERLAP_LEFT_SIDE) { - SEQ_time_left_handle_frame_set(seq, transformed->enddisp); + SEQ_time_left_handle_frame_set(scene, seq, SEQ_time_right_handle_frame_get(transformed)); } else { BLI_assert(overlap == STRIP_OVERLAP_RIGHT_SIDE); - SEQ_time_right_handle_frame_set(seq, transformed->startdisp); + SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(transformed)); } - - SEQ_time_update_sequence(scene, seqbasep, seq); } SEQ_collection_free(targets); } @@ -577,11 +562,6 @@ void SEQ_transform_handle_overlap(Scene *scene, break; } - if (seq_transform_check_strip_effects(transformed_strips)) { - /* Update effect strips based on strips just moved in time. */ - seq_transform_update_effects(scene, seqbasep, transformed_strips); - } - /* If any effects still overlap, we need to move them up. * In some cases other strips can be overlapping still, see T90646. */ Sequence *seq; @@ -635,10 +615,7 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c SEQ_transform_handle_overlap(scene, seqbasep, transformed_strips, use_sync_markers); } - seq_transform_update_effects(scene, seqbasep, transformed_strips); SEQ_collection_free(transformed_strips); - - SEQ_sort(ed->seqbasep); DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS); free_transform_custom_data(custom_data); } @@ -662,7 +639,10 @@ typedef enum SeqInputSide { static Sequence *effect_input_get(Sequence *effect, SeqInputSide side) { Sequence *input = effect->seq1; - if (effect->seq2 && (effect->seq2->startdisp - effect->seq1->startdisp) * side > 0) { + if (effect->seq2 && (SEQ_time_left_handle_frame_get(effect->seq2) - + SEQ_time_left_handle_frame_get(effect->seq1)) * + side > + 0) { input = effect->seq2; } return input; @@ -825,23 +805,6 @@ void createTransSeqData(TransInfo *t) /** \name UVs Transform Flush * \{ */ -/* commented _only_ because the meta may have animation data which - * needs moving too T28158. */ - -BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int sel_flag) -{ - /* Calculate this strip and all nested strips. - * Children are ALWAYS transformed first so we don't need to do this in another loop. - */ - - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(sce)); - SEQ_time_update_sequence(sce, seqbase, seq); - - if (sel_flag == SELECT) { - SEQ_offset_animdata(sce, seq, seq->start - old_start); - } -} - static void view2d_edge_pan_loc_compensate(TransInfo *t, float loc_in[2], float r_loc[2]) { TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data; @@ -914,24 +877,24 @@ static void flushTransSeq(TransInfo *t) break; } case SEQ_LEFTSEL: { /* No vertical transform. */ - int old_startdisp = seq->startdisp; - SEQ_time_left_handle_frame_set(seq, new_frame); - SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); - SEQ_transform_fix_single_image_seq_offsets(seq); - SEQ_time_update_sequence(t->scene, seqbasep, seq); - if (abs(seq->startdisp - old_startdisp) > abs(max_offset)) { - max_offset = seq->startdisp - old_startdisp; + int old_startdisp = SEQ_time_left_handle_frame_get(seq); + SEQ_time_left_handle_frame_set(t->scene, seq, new_frame); + SEQ_transform_handle_xlimits( + t->scene, seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); + SEQ_transform_fix_single_image_seq_offsets(t->scene, seq); + if (abs(SEQ_time_left_handle_frame_get(seq) - old_startdisp) > abs(max_offset)) { + max_offset = SEQ_time_left_handle_frame_get(seq) - old_startdisp; } break; } case SEQ_RIGHTSEL: { /* No vertical transform. */ - int old_enddisp = seq->enddisp; - SEQ_time_right_handle_frame_set(seq, new_frame); - SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); - SEQ_transform_fix_single_image_seq_offsets(seq); - SEQ_time_update_sequence(t->scene, seqbasep, seq); - if (abs(seq->enddisp - old_enddisp) > abs(max_offset)) { - max_offset = seq->enddisp - old_enddisp; + int old_enddisp = SEQ_time_right_handle_frame_get(seq); + SEQ_time_right_handle_frame_set(t->scene, seq, new_frame); + SEQ_transform_handle_xlimits( + t->scene, seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); + SEQ_transform_fix_single_image_seq_offsets(t->scene, seq); + if (abs(SEQ_time_right_handle_frame_get(seq) - old_enddisp) > abs(max_offset)) { + max_offset = SEQ_time_right_handle_frame_get(seq) - old_enddisp; } break; } @@ -945,15 +908,6 @@ static void flushTransSeq(TransInfo *t) SEQ_offset_animdata(t->scene, seq, max_offset); } - /* Update effect length and position. */ - if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) { - for (seq = seqbasep->first; seq; seq = seq->next) { - if (seq->seq1 || seq->seq2 || seq->seq3) { - SEQ_time_update_sequence(t->scene, seqbasep, seq); - } - } - } - /* need to do the overlap check in a new loop otherwise adjacent strips * will not be updated and we'll get false positives */ SeqCollection *transformed_strips = seq_transform_collection_from_transdata(tc); diff --git a/source/blender/editors/transform/transform_snap_sequencer.c b/source/blender/editors/transform/transform_snap_sequencer.c index 7dc361ff5bb..dbcae2b6320 100644 --- a/source/blender/editors/transform/transform_snap_sequencer.c +++ b/source/blender/editors/transform/transform_snap_sequencer.c @@ -25,6 +25,7 @@ #include "SEQ_relations.h" #include "SEQ_render.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" #include "transform.h" #include "transform_snap.h" @@ -65,14 +66,14 @@ static void seq_snap_source_points_build(TransSeqSnapData *snap_data, SeqCollect SEQ_ITERATOR_FOREACH (seq, snap_sources) { int left = 0, right = 0; if (seq->flag & SEQ_LEFTSEL) { - left = right = seq->startdisp; + left = right = SEQ_time_left_handle_frame_get(seq); } else if (seq->flag & SEQ_RIGHTSEL) { - left = right = seq->enddisp; + left = right = SEQ_time_right_handle_frame_get(seq); } else { - left = seq->startdisp; - right = seq->enddisp; + left = SEQ_time_left_handle_frame_get(seq); + right = SEQ_time_right_handle_frame_get(seq); } snap_data->source_snap_points[i] = left; @@ -193,21 +194,24 @@ static void seq_snap_target_points_build(Scene *scene, Sequence *seq; SEQ_ITERATOR_FOREACH (seq, snap_targets) { - snap_data->target_snap_points[i] = seq->startdisp; - snap_data->target_snap_points[i + 1] = seq->enddisp; + snap_data->target_snap_points[i] = SEQ_time_left_handle_frame_get(seq); + snap_data->target_snap_points[i + 1] = SEQ_time_right_handle_frame_get(seq); i += 2; if (snap_mode & SEQ_SNAP_TO_STRIP_HOLD) { - int content_start = min_ii(seq->enddisp, seq->start); - int content_end = max_ii(seq->startdisp, seq->start + seq->len); + int content_start = min_ii(SEQ_time_right_handle_frame_get(seq), seq->start); + int content_end = max_ii(SEQ_time_left_handle_frame_get(seq), seq->start + seq->len); /* Effects and single image strips produce incorrect content length. Skip these strips. */ if ((seq->type & SEQ_TYPE_EFFECT) != 0 || seq->len == 1) { - content_start = seq->startdisp; - content_end = seq->enddisp; + content_start = SEQ_time_left_handle_frame_get(seq); + content_end = SEQ_time_right_handle_frame_get(seq); } - CLAMP(content_start, seq->startdisp, seq->enddisp); - CLAMP(content_end, seq->startdisp, seq->enddisp); + CLAMP(content_start, + SEQ_time_left_handle_frame_get(seq), + SEQ_time_right_handle_frame_get(seq)); + CLAMP( + content_end, SEQ_time_left_handle_frame_get(seq), SEQ_time_right_handle_frame_get(seq)); snap_data->target_snap_points[i] = content_start; snap_data->target_snap_points[i + 1] = content_end; diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index ead017a91bf..cea2bb05547 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -2425,7 +2425,7 @@ static bool uv_mouse_select_multi(bContext *C, UvNearestHit hit = UV_NEAREST_HIT_INIT_DIST_PX(®ion->v2d, 75.0f); int selectmode, sticky; bool found_item = false; - /* 0 == don't flush, 1 == sel, -1 == desel; only use when selection sync is enabled */ + /* 0 == don't flush, 1 == sel, -1 == deselect; only use when selection sync is enabled. */ int flush = 0; /* Penalty (in pixels) applied to elements that are already selected @@ -2514,8 +2514,15 @@ static bool uv_mouse_select_multi(bContext *C, else if (selectmode == UV_SELECT_EDGE) { is_selected = uvedit_edge_select_test(scene, hit.l, cd_loop_uv_offset); } - else { /* Vertex or island. */ - is_selected = uvedit_uv_select_test(scene, hit.l, cd_loop_uv_offset); + else { + /* Vertex or island. For island (if we were using #uv_find_nearest_face_multi_ex, see above), + * `hit.l` is NULL, use `hit.efa` instead. */ + if (hit.l != NULL) { + is_selected = uvedit_uv_select_test(scene, hit.l, cd_loop_uv_offset); + } + else { + is_selected = uvedit_face_select_test(scene, hit.efa, cd_loop_uv_offset); + } } } @@ -2728,7 +2735,7 @@ static int uv_mouse_select_loop_generic_multi(bContext *C, const ToolSettings *ts = scene->toolsettings; UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); bool found_item = false; - /* 0 == don't flush, 1 == sel, -1 == desel; only use when selection sync is enabled */ + /* 0 == don't flush, 1 == sel, -1 == deselect; only use when selection sync is enabled. */ int flush = 0; /* Find edge. */ @@ -3282,8 +3289,6 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, efa_index) { if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { - /* tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); */ /* UNUSED */ - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); if (select) { @@ -3353,8 +3358,6 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co /* now select tagged verts */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - /* tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); */ /* UNUSED */ - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) { uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset); @@ -3373,8 +3376,6 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co } BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, efa_index) { - /* tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); */ /* UNUSED */ - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l, BM_ELEM_TAG)) { uv_select_flush_from_tag_sticky_loc_internal( diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index bacf321fce1..55e44607f6f 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1716,7 +1716,7 @@ static void stitch_draw_vbo(GPUVertBuf *vbo, GPUPrimType prim_type, const float GPU_batch_discard(batch); } -/* TODO: make things pretier : store batches inside StitchPreviewer instead of the bare verts pos +/* TODO: make things prettier : store batches inside StitchPreviewer instead of the bare verts pos */ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void *arg) { diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 84dca352c9f..cbc9b2a8d06 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -301,22 +301,19 @@ void ED_uvedit_get_aspect(Object *ob, float *r_aspx, float *r_aspy) static void construct_param_handle_face_add(ParamHandle *handle, const Scene *scene, BMFace *efa, - int face_index, + ParamKey face_index, const int cd_loop_uv_offset) { - ParamKey key; ParamKey *vkeys = BLI_array_alloca(vkeys, efa->len); - ParamBool *pin = BLI_array_alloca(pin, efa->len); - ParamBool *select = BLI_array_alloca(select, efa->len); - float **co = BLI_array_alloca(co, efa->len); + bool *pin = BLI_array_alloca(pin, efa->len); + bool *select = BLI_array_alloca(select, efa->len); + const float **co = BLI_array_alloca(co, efa->len); float **uv = BLI_array_alloca(uv, efa->len); int i; BMIter liter; BMLoop *l; - key = (ParamKey)face_index; - /* let parametrizer split the ngon, it can make better decisions * about which split is best for unwrapping than poly-fill. */ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { @@ -329,7 +326,7 @@ static void construct_param_handle_face_add(ParamHandle *handle, select[i] = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); } - GEO_uv_parametrizer_face_add(handle, key, i, vkeys, co, uv, pin, select); + GEO_uv_parametrizer_face_add(handle, face_index, i, vkeys, co, uv, pin, select); } /* See: construct_param_handle_multi to handle multiple objects at once. */ @@ -500,8 +497,8 @@ static void texface_from_original_index(const Scene *scene, BMFace *efa, int index, float **r_uv, - ParamBool *r_pin, - ParamBool *r_select) + bool *r_pin, + bool *r_select) { BMLoop *l; BMIter liter; @@ -633,8 +630,8 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, /* Prepare and feed faces to the solver */ for (i = 0, mpoly = subsurfedPolys; i < numOfFaces; i++, mpoly++) { ParamKey key, vkeys[4]; - ParamBool pin[4], select[4]; - float *co[4]; + bool pin[4], select[4]; + const float *co[4]; float *uv[4]; BMFace *origFace = faceMap[i]; @@ -652,7 +649,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, mloop = &subsurfedLoops[mpoly->loopstart]; - /* We will not check for v4 here. Subsurfed mfaces always have 4 vertices. */ + /* We will not check for v4 here. Sub-surface faces always have 4 vertices. */ BLI_assert(mpoly->totloop == 4); key = (ParamKey)i; vkeys[0] = (ParamKey)mloop[0].v; @@ -1245,7 +1242,7 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) handle = construct_param_handle(scene, obedit, em->bm, &options, NULL); } - GEO_uv_parametrizer_lscm_begin(handle, PARAM_TRUE, abf); + GEO_uv_parametrizer_lscm_begin(handle, true, abf); /* Create or increase size of g_live_unwrap.handles array */ if (g_live_unwrap.handles == NULL) { @@ -1796,7 +1793,7 @@ static void uvedit_unwrap(const Scene *scene, handle = construct_param_handle(scene, obedit, em->bm, options, result_info); } - GEO_uv_parametrizer_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0); + GEO_uv_parametrizer_lscm_begin(handle, false, scene->toolsettings->unwrapper == 0); GEO_uv_parametrizer_lscm_solve(handle, result_info ? &result_info->count_changed : NULL, result_info ? &result_info->count_failed : NULL); diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index 9d09378ab63..16a33c9cda7 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -41,6 +41,10 @@ class MFParamsBuilder { MFParamsBuilder(const MFSignature &signature, const IndexMask mask) : signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size()) { + virtual_arrays_.reserve(signature.virtual_array_num); + mutable_spans_.reserve(signature.span_num); + virtual_vector_arrays_.reserve(signature.virtual_vector_array_num); + vector_arrays_.reserve(signature.vector_array_num); } public: @@ -53,28 +57,33 @@ class MFParamsBuilder { template<typename T> void add_readonly_single_input_value(T value, StringRef expected_name = "") { - this->add_readonly_single_input(VArray<T>::ForSingle(std::move(value), min_array_size_), - expected_name); + this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get<T>()), expected_name); + virtual_arrays_.append_unchecked_as( + varray_tag::single{}, CPPType::get<T>(), min_array_size_, &value); } template<typename T> void add_readonly_single_input(const T *value, StringRef expected_name = "") { - this->add_readonly_single_input( - GVArray::ForSingleRef(CPPType::get<T>(), min_array_size_, value), expected_name); + this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get<T>()), expected_name); + virtual_arrays_.append_unchecked_as( + varray_tag::single_ref{}, CPPType::get<T>(), min_array_size_, value); } void add_readonly_single_input(const GSpan span, StringRef expected_name = "") { - this->add_readonly_single_input(GVArray::ForSpan(span), expected_name); + this->assert_current_param_type(MFParamType::ForSingleInput(span.type()), expected_name); + BLI_assert(span.size() >= min_array_size_); + virtual_arrays_.append_unchecked_as(varray_tag::span{}, span); } void add_readonly_single_input(GPointer value, StringRef expected_name = "") { - this->add_readonly_single_input( - GVArray::ForSingleRef(*value.type(), min_array_size_, value.get()), expected_name); + this->assert_current_param_type(MFParamType::ForSingleInput(*value.type()), expected_name); + virtual_arrays_.append_unchecked_as( + varray_tag::single_ref{}, *value.type(), min_array_size_, value.get()); } void add_readonly_single_input(GVArray varray, StringRef expected_name = "") { this->assert_current_param_type(MFParamType::ForSingleInput(varray.type()), expected_name); BLI_assert(varray.size() >= min_array_size_); - virtual_arrays_.append(varray); + virtual_arrays_.append_unchecked_as(std::move(varray)); } void add_readonly_vector_input(const GVectorArray &vector_array, StringRef expected_name = "") @@ -92,7 +101,7 @@ class MFParamsBuilder { { this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); - virtual_vector_arrays_.append(&ref); + virtual_vector_arrays_.append_unchecked(&ref); } template<typename T> void add_uninitialized_single_output(T *value, StringRef expected_name = "") @@ -104,7 +113,7 @@ class MFParamsBuilder { { this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); - mutable_spans_.append(ref); + mutable_spans_.append_unchecked(ref); } void add_ignored_single_output(StringRef expected_name = "") { @@ -115,7 +124,7 @@ class MFParamsBuilder { const CPPType &type = param_type.data_type().single_type(); /* An empty span indicates that this is ignored. */ const GMutableSpan dummy_span{type}; - mutable_spans_.append(dummy_span); + mutable_spans_.append_unchecked(dummy_span); } void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "") @@ -123,14 +132,14 @@ class MFParamsBuilder { this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()), expected_name); BLI_assert(vector_array.size() >= min_array_size_); - vector_arrays_.append(&vector_array); + vector_arrays_.append_unchecked(&vector_array); } void add_single_mutable(GMutableSpan ref, StringRef expected_name = "") { this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); - mutable_spans_.append(ref); + mutable_spans_.append_unchecked(ref); } void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "") @@ -138,7 +147,7 @@ class MFParamsBuilder { this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()), expected_name); BLI_assert(vector_array.size() >= min_array_size_); - vector_arrays_.append(&vector_array); + vector_arrays_.append_unchecked(&vector_array); } GMutableSpan computed_array(int param_index) diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh index 62c491609a4..6181555dbd1 100644 --- a/source/blender/functions/FN_multi_function_signature.hh +++ b/source/blender/functions/FN_multi_function_signature.hh @@ -29,6 +29,15 @@ struct MFSignature { Vector<int> param_data_indices; bool depends_on_context = false; + /** + * Number of elements of each of these types that has to be passed into the multi-function as an + * input or output. + */ + int span_num = 0; + int virtual_array_num = 0; + int virtual_vector_array_num = 0; + int vector_array_num = 0; + int data_index(int param_index) const { return param_data_indices[param_index]; @@ -38,10 +47,6 @@ struct MFSignature { class MFSignatureBuilder { private: MFSignature signature_; - int span_count_ = 0; - int virtual_array_count_ = 0; - int virtual_vector_array_count_ = 0; - int vector_array_count_ = 0; public: MFSignatureBuilder(const char *function_name) @@ -79,10 +84,10 @@ class MFSignatureBuilder { switch (data_type.category()) { case MFDataType::Single: - signature_.param_data_indices.append(virtual_array_count_++); + signature_.param_data_indices.append(signature_.virtual_array_num++); break; case MFDataType::Vector: - signature_.param_data_indices.append(virtual_vector_array_count_++); + signature_.param_data_indices.append(signature_.virtual_vector_array_num++); break; } } @@ -112,10 +117,10 @@ class MFSignatureBuilder { switch (data_type.category()) { case MFDataType::Single: - signature_.param_data_indices.append(span_count_++); + signature_.param_data_indices.append(signature_.span_num++); break; case MFDataType::Vector: - signature_.param_data_indices.append(vector_array_count_++); + signature_.param_data_indices.append(signature_.vector_array_num++); break; } } @@ -145,10 +150,10 @@ class MFSignatureBuilder { switch (data_type.category()) { case MFDataType::Single: - signature_.param_data_indices.append(span_count_++); + signature_.param_data_indices.append(signature_.span_num++); break; case MFDataType::Vector: - signature_.param_data_indices.append(vector_array_count_++); + signature_.param_data_indices.append(signature_.vector_array_num++); break; } } diff --git a/source/blender/geometry/GEO_uv_parametrizer.h b/source/blender/geometry/GEO_uv_parametrizer.h index 624b0695aa3..7fe60a3a855 100644 --- a/source/blender/geometry/GEO_uv_parametrizer.h +++ b/source/blender/geometry/GEO_uv_parametrizer.h @@ -14,10 +14,6 @@ extern "C" { typedef struct ParamHandle ParamHandle; /* Handle to an array of charts. */ typedef intptr_t ParamKey; /* Key (hash) for identifying verts and faces. */ -typedef enum ParamBool { - PARAM_TRUE = 1, - PARAM_FALSE = 0, -} ParamBool; /* -------------------------------------------------------------------- */ /** \name Chart Construction: @@ -39,19 +35,19 @@ ParamHandle *GEO_uv_parametrizer_construct_begin(void); void GEO_uv_parametrizer_aspect_ratio(ParamHandle *handle, float aspx, float aspy); void GEO_uv_parametrizer_face_add(ParamHandle *handle, - ParamKey key, - int nverts, - ParamKey *vkeys, - float *co[4], - float *uv[4], - ParamBool *pin, - ParamBool *select); + const ParamKey key, + const int nverts, + const ParamKey *vkeys, + const float **co, + float **uv, /* Output will eventually be written to `uv`. */ + const bool *pin, + const bool *select); void GEO_uv_parametrizer_edge_set_seam(ParamHandle *handle, ParamKey *vkeys); void GEO_uv_parametrizer_construct_end(ParamHandle *handle, - ParamBool fill, - ParamBool topology_from_uvs, + bool fill, + bool topology_from_uvs, int *count_fail); void GEO_uv_parametrizer_delete(ParamHandle *handle); @@ -70,7 +66,7 @@ void GEO_uv_parametrizer_delete(ParamHandle *handle); * * \{ */ -void GEO_uv_parametrizer_lscm_begin(ParamHandle *handle, ParamBool live, ParamBool abf); +void GEO_uv_parametrizer_lscm_begin(ParamHandle *handle, bool live, bool abf); void GEO_uv_parametrizer_lscm_solve(ParamHandle *handle, int *count_changed, int *count_failed); void GEO_uv_parametrizer_lscm_end(ParamHandle *handle); @@ -88,14 +84,6 @@ void GEO_uv_parametrizer_stretch_end(ParamHandle *handle); /** \} */ /* -------------------------------------------------------------------- */ -/** \name Area Smooth - * \{ */ - -void GEO_uv_parametrizer_smooth_area(ParamHandle *handle); - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Packing * \{ */ diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index ae07e817c67..4db4256ec8f 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -279,12 +279,12 @@ static void copy_generic_attributes_to_result( const Span<std::optional<GVArray_GSpan>> src_attributes, const AttributeFallbacksArray &attribute_fallbacks, const OrderedAttributes &ordered_attributes, - const FunctionRef<IndexRange(AttributeDomain)> &range_fn, + const FunctionRef<IndexRange(eAttrDomain)> &range_fn, MutableSpan<GMutableSpan> dst_attributes) { threading::parallel_for(dst_attributes.index_range(), 10, [&](const IndexRange attribute_range) { for (const int attribute_index : attribute_range) { - const AttributeDomain domain = ordered_attributes.kinds[attribute_index].domain; + const eAttrDomain domain = ordered_attributes.kinds[attribute_index].domain; const IndexRange element_slice = range_fn(domain); GMutableSpan dst_span = dst_attributes[attribute_index].slice(element_slice); @@ -363,7 +363,7 @@ static Vector<std::pair<int, GSpan>> prepare_attribute_fallbacks( return true; } GSpan span = *attributes.get_for_read(attribute_id); - const CustomDataType expected_type = ordered_attributes.kinds[attribute_index].data_type; + const eCustomDataType expected_type = ordered_attributes.kinds[attribute_index].data_type; if (meta_data.data_type != expected_type) { const CPPType &from_type = span.type(); const CPPType &to_type = *custom_data_type_to_cpp_type(expected_type); @@ -644,8 +644,8 @@ static AllPointCloudsInfo preprocess_pointclouds(const GeometrySet &geometry_set pointcloud_info.attributes.reinitialize(info.attributes.size()); for (const int attribute_index : info.attributes.index_range()) { const AttributeIDRef &attribute_id = info.attributes.ids[attribute_index]; - const CustomDataType data_type = info.attributes.kinds[attribute_index].data_type; - const AttributeDomain domain = info.attributes.kinds[attribute_index].domain; + const eCustomDataType data_type = info.attributes.kinds[attribute_index].data_type; + const eAttrDomain domain = info.attributes.kinds[attribute_index].domain; if (component.attribute_exists(attribute_id)) { GVArray attribute = component.attribute_get_for_read(attribute_id, domain, data_type); pointcloud_info.attributes[attribute_index].emplace(std::move(attribute)); @@ -687,7 +687,7 @@ static void execute_realize_pointcloud_task(const RealizeInstancesOptions &optio pointcloud_info.attributes, task.attribute_fallbacks, ordered_attributes, - [&](const AttributeDomain domain) { + [&](const eAttrDomain domain) { BLI_assert(domain == ATTR_DOMAIN_POINT); UNUSED_VARS_NDEBUG(domain); return point_slice; @@ -728,7 +728,7 @@ static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &opti Vector<GMutableSpan> dst_attribute_spans; for (const int attribute_index : ordered_attributes.index_range()) { const AttributeIDRef &attribute_id = ordered_attributes.ids[attribute_index]; - const CustomDataType data_type = ordered_attributes.kinds[attribute_index].data_type; + const eCustomDataType data_type = ordered_attributes.kinds[attribute_index].data_type; OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only( attribute_id, ATTR_DOMAIN_POINT, data_type); dst_attribute_spans.append(dst_attribute.as_span()); @@ -835,8 +835,8 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set, mesh_info.attributes.reinitialize(info.attributes.size()); for (const int attribute_index : info.attributes.index_range()) { const AttributeIDRef &attribute_id = info.attributes.ids[attribute_index]; - const CustomDataType data_type = info.attributes.kinds[attribute_index].data_type; - const AttributeDomain domain = info.attributes.kinds[attribute_index].domain; + const eCustomDataType data_type = info.attributes.kinds[attribute_index].data_type; + const eAttrDomain domain = info.attributes.kinds[attribute_index].domain; if (component.attribute_exists(attribute_id)) { GVArray attribute = component.attribute_get_for_read(attribute_id, domain, data_type); mesh_info.attributes[attribute_index].emplace(std::move(attribute)); @@ -927,7 +927,7 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options, mesh_info.attributes, task.attribute_fallbacks, ordered_attributes, - [&](const AttributeDomain domain) { + [&](const eAttrDomain domain) { switch (domain) { case ATTR_DOMAIN_POINT: return IndexRange(task.start_indices.vertex, mesh.totvert); @@ -991,8 +991,8 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, Vector<GMutableSpan> dst_attribute_spans; for (const int attribute_index : ordered_attributes.index_range()) { const AttributeIDRef &attribute_id = ordered_attributes.ids[attribute_index]; - const AttributeDomain domain = ordered_attributes.kinds[attribute_index].domain; - const CustomDataType data_type = ordered_attributes.kinds[attribute_index].data_type; + const eAttrDomain domain = ordered_attributes.kinds[attribute_index].domain; + const eCustomDataType data_type = ordered_attributes.kinds[attribute_index].data_type; OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only( attribute_id, domain, data_type); dst_attribute_spans.append(dst_attribute.as_span()); @@ -1083,9 +1083,9 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set, component.replace(const_cast<Curves *>(curves), GeometryOwnershipType::ReadOnly); curve_info.attributes.reinitialize(info.attributes.size()); for (const int attribute_index : info.attributes.index_range()) { - const AttributeDomain domain = info.attributes.kinds[attribute_index].domain; + const eAttrDomain domain = info.attributes.kinds[attribute_index].domain; const AttributeIDRef &attribute_id = info.attributes.ids[attribute_index]; - const CustomDataType data_type = info.attributes.kinds[attribute_index].data_type; + const eCustomDataType data_type = info.attributes.kinds[attribute_index].data_type; if (component.attribute_exists(attribute_id)) { GVArray attribute = component.attribute_get_for_read(attribute_id, domain, data_type); curve_info.attributes[attribute_index].emplace(std::move(attribute)); @@ -1189,7 +1189,7 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options, curves_info.attributes, task.attribute_fallbacks, ordered_attributes, - [&](const AttributeDomain domain) { + [&](const eAttrDomain domain) { switch (domain) { case ATTR_DOMAIN_POINT: return IndexRange(task.start_indices.point, curves.points_num()); @@ -1238,8 +1238,8 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options, Vector<GMutableSpan> dst_attribute_spans; for (const int attribute_index : ordered_attributes.index_range()) { const AttributeIDRef &attribute_id = ordered_attributes.ids[attribute_index]; - const AttributeDomain domain = ordered_attributes.kinds[attribute_index].domain; - const CustomDataType data_type = ordered_attributes.kinds[attribute_index].data_type; + const eAttrDomain domain = ordered_attributes.kinds[attribute_index].domain; + const eCustomDataType data_type = ordered_attributes.kinds[attribute_index].data_type; OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only( attribute_id, domain, data_type); dst_attribute_spans.append(dst_attribute.as_span()); diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index 7895225a189..9eaab327e01 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -99,7 +99,7 @@ static void retrieve_attribute_spans(const Span<bke::AttributeIDRef> ids, BLI_assert(src_attribute); src.append(src_attribute.get_internal_span()); - const CustomDataType data_type = bke::cpp_type_to_custom_data_type(src_attribute.type()); + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(src_attribute.type()); bke::OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only( ids[i], ATTR_DOMAIN_POINT, data_type); dst.append(dst_attribute.as_span()); diff --git a/source/blender/geometry/intern/uv_parametrizer.c b/source/blender/geometry/intern/uv_parametrizer.c index ad4b051a6c2..af3bcc3bdec 100644 --- a/source/blender/geometry/intern/uv_parametrizer.c +++ b/source/blender/geometry/intern/uv_parametrizer.c @@ -36,11 +36,6 @@ #define param_warning(message) \ {/*printf("Warning %s:%d: %s\n", __FILE__, __LINE__, message);*/}(void)0 -typedef enum PBool { - P_TRUE = 1, - P_FALSE = 0, -} PBool; - /* Special Purpose Hash */ typedef intptr_t PHashKey; @@ -509,53 +504,26 @@ static void UNUSED_FUNCTION(p_chart_uv_from_array)(PChart *chart, float (*points } } -static PBool p_intersect_line_2d_dir(const float v1[2], - const float dir1[2], - const float v2[2], - const float dir2[2], - float r_isect[2]) +static bool p_intersect_line_2d_dir(const float v1[2], + const float dir1[2], + const float v2[2], + const float dir2[2], + float r_isect[2]) { float lmbda, div; div = dir2[0] * dir1[1] - dir2[1] * dir1[0]; if (div == 0.0f) { - return P_FALSE; + return false; } lmbda = ((v1[1] - v2[1]) * dir1[0] - (v1[0] - v2[0]) * dir1[1]) / div; r_isect[0] = v1[0] + lmbda * dir2[0]; r_isect[1] = v1[1] + lmbda * dir2[1]; - return P_TRUE; -} - -#if 0 -static PBool p_intersect_line_2d(const float v1[2], - const float v2[2], - const float v3[2], - const float v4[2], - const float r_isect[2]) -{ - float dir1[2], dir2[2]; - - dir1[0] = v4[0] - v3[0]; - dir1[1] = v4[1] - v3[1]; - - dir2[0] = v2[0] - v1[0]; - dir2[1] = v2[1] - v1[1]; - - if (!p_intersect_line_2d_dir(v1, dir1, v2, dir2, isect)) { - /* parallel - should never happen in theory for polygon kernel, but - * let's give a point nearby in case things go wrong */ - isect[0] = (v1[0] + v2[0]) * 0.5f; - isect[1] = (v1[1] + v2[1]) * 0.5f; - return P_FALSE; - } - - return P_TRUE; + return true; } -#endif /* Topological Utilities */ @@ -586,9 +554,9 @@ static PEdge *p_boundary_edge_prev(PEdge *e) return last->next->next; } -static PBool p_vert_interior(PVert *v) +static bool p_vert_interior(PVert *v) { - return (v->edge->pair != NULL); + return v->edge->pair; } static void p_face_flip(PFace *f) @@ -807,7 +775,7 @@ static PEdge *p_edge_lookup(ParamHandle *handle, const PHashKey *vkeys) return NULL; } -static int p_face_exists(ParamHandle *handle, ParamKey *pvkeys, int i1, int i2, int i3) +static int p_face_exists(ParamHandle *handle, const ParamKey *pvkeys, int i1, int i2, int i3) { PHashKey *vkeys = (PHashKey *)pvkeys; PHashKey key = PHASH_edge(vkeys[i1], vkeys[i2]); @@ -816,19 +784,19 @@ static int p_face_exists(ParamHandle *handle, ParamKey *pvkeys, int i1, int i2, while (e) { if ((e->vert->u.key == vkeys[i1]) && (e->next->vert->u.key == vkeys[i2])) { if (e->next->next->vert->u.key == vkeys[i3]) { - return P_TRUE; + return true; } } else if ((e->vert->u.key == vkeys[i2]) && (e->next->vert->u.key == vkeys[i1])) { if (e->next->next->vert->u.key == vkeys[i3]) { - return P_TRUE; + return true; } } e = (PEdge *)phash_next(handle->hash_edges, key, (PHashLink *)e); } - return P_FALSE; + return false; } static PChart *p_chart_new(ParamHandle *handle) @@ -845,7 +813,7 @@ static void p_chart_delete(PChart *chart) MEM_freeN(chart); } -static PBool p_edge_implicit_seam(PEdge *e, PEdge *ep) +static bool p_edge_implicit_seam(PEdge *e, PEdge *ep) { float *uv1, *uv2, *uvp1, *uvp2; float limit[2]; @@ -868,21 +836,18 @@ static PBool p_edge_implicit_seam(PEdge *e, PEdge *ep) if ((fabsf(uv1[0] - uvp1[0]) > limit[0]) || (fabsf(uv1[1] - uvp1[1]) > limit[1])) { e->flag |= PEDGE_SEAM; ep->flag |= PEDGE_SEAM; - return P_TRUE; + return true; } if ((fabsf(uv2[0] - uvp2[0]) > limit[0]) || (fabsf(uv2[1] - uvp2[1]) > limit[1])) { e->flag |= PEDGE_SEAM; ep->flag |= PEDGE_SEAM; - return P_TRUE; + return true; } - return P_FALSE; + return false; } -static PBool p_edge_has_pair(ParamHandle *handle, - PEdge *e, - PBool topology_from_uvs, - PEdge **r_pair) +static bool p_edge_has_pair(ParamHandle *handle, PEdge *e, bool topology_from_uvs, PEdge **r_pair) { PHashKey key; PEdge *pe; @@ -891,7 +856,7 @@ static PBool p_edge_has_pair(ParamHandle *handle, PHashKey key2 = e->next->vert->u.key; if (e->flag & PEDGE_SEAM) { - return P_FALSE; + return false; } key = PHASH_edge(key1, key2); @@ -910,7 +875,7 @@ static PBool p_edge_has_pair(ParamHandle *handle, if ((pe->flag & PEDGE_SEAM) || *r_pair || (topology_from_uvs && p_edge_implicit_seam(e, pe))) { *r_pair = NULL; - return P_FALSE; + return false; } *r_pair = pe; @@ -924,17 +889,17 @@ static PBool p_edge_has_pair(ParamHandle *handle, if ((*r_pair)->next->pair || (*r_pair)->next->next->pair) { /* non unfoldable, maybe mobius ring or klein bottle */ *r_pair = NULL; - return P_FALSE; + return false; } } return (*r_pair != NULL); } -static PBool p_edge_connect_pair(ParamHandle *handle, - PEdge *e, - PBool topology_from_uvs, - PEdge ***stack) +static bool p_edge_connect_pair(ParamHandle *handle, + PEdge *e, + bool topology_from_uvs, + PEdge ***stack) { PEdge *pair = NULL; @@ -955,7 +920,7 @@ static PBool p_edge_connect_pair(ParamHandle *handle, return (e->pair != NULL); } -static int p_connect_pairs(ParamHandle *handle, PBool topology_from_uvs) +static int p_connect_pairs(ParamHandle *handle, bool topology_from_uvs) { PEdge **stackbase = MEM_mallocN(sizeof(*stackbase) * phash_size(handle->hash_faces), "Pstackbase"); @@ -1009,7 +974,7 @@ static void p_split_vert(PChart *chart, PEdge *e) { PEdge *we, *lastwe = NULL; PVert *v = e->vert; - PBool copy = P_TRUE; + bool copy = true; if (e->flag & PEDGE_PIN) { chart->flag |= PCHART_HAS_PINS; @@ -1035,7 +1000,7 @@ static void p_split_vert(PChart *chart, PEdge *e) if (we == v->edge) { /* found it, no need to copy */ - copy = P_FALSE; + copy = false; v->nextlink = chart->verts; chart->verts = v; chart->nverts++; @@ -1136,13 +1101,13 @@ static PFace *p_face_add(ParamHandle *handle) static PFace *p_face_add_construct(ParamHandle *handle, ParamKey key, const ParamKey *vkeys, - float *co[4], - float *uv[4], + const float **co, + float **uv, int i1, int i2, int i3, - const ParamBool *pin, - const ParamBool *select) + const bool *pin, + const bool *select) { PFace *f = p_face_add(handle); PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; @@ -1179,7 +1144,6 @@ static PFace *p_face_add_construct(ParamHandle *handle, } } - /* insert into hash */ f->u.key = key; phash_insert(handle->hash_faces, (PHashLink *)f); @@ -1220,14 +1184,14 @@ static PFace *p_face_add_fill(PChart *chart, PVert *v1, PVert *v2, PVert *v3) return f; } -static PBool p_quad_split_direction(ParamHandle *handle, float **co, PHashKey *vkeys) +static bool p_quad_split_direction(ParamHandle *handle, const float **co, const ParamKey *vkeys) { /* Slight bias to prefer one edge over the other in case they are equal, so * that in symmetric models we choose the same split direction instead of * depending on floating point errors to decide. */ float bias = 1.0f + 1e-6f; float fac = len_v3v3(co[0], co[2]) * bias - len_v3v3(co[1], co[3]); - PBool dir = (fac <= 0.0f); + bool dir = (fac <= 0.0f); /* The face exists check is there because of a special case: * when two quads share three vertices, they can each be split into two triangles, @@ -1566,22 +1530,22 @@ static float p_vert_cotan(const float v1[3], const float v2[3], const float v3[3 return dot_v3v3(a, b) / clen; } -static PBool p_vert_flipped_wheel_triangle(PVert *v) +static bool p_vert_flipped_wheel_triangle(PVert *v) { PEdge *e = v->edge; do { if (p_face_uv_area_signed(e->face) < 0.0f) { - return P_TRUE; + return true; } e = p_wheel_edge_next(e); } while (e && (e != v->edge)); - return P_FALSE; + return false; } -static PBool p_vert_map_harmonic_weights(PVert *v) +static bool p_vert_map_harmonic_weights(PVert *v) { float weightsum, positionsum[2], olduv[2]; @@ -1647,10 +1611,10 @@ static PBool p_vert_map_harmonic_weights(PVert *v) v->uv[0] = olduv[0]; v->uv[1] = olduv[1]; - return P_FALSE; + return false; } - return P_TRUE; + return true; } static void p_vert_harmonic_insert(PVert *v) @@ -1883,7 +1847,7 @@ static void p_split_vertex(PEdge *edge, PEdge *pair) } while (e && (e != newv->edge)); } -static PBool p_collapse_allowed_topologic(PEdge *edge, PEdge *pair) +static bool p_collapse_allowed_topologic(PEdge *edge, PEdge *pair) { PVert *oldv, *keepv; @@ -1893,22 +1857,22 @@ static PBool p_collapse_allowed_topologic(PEdge *edge, PEdge *pair) if (!edge || !pair) { /* avoid collapsing chart into an edge */ if (edge && !edge->next->pair && !edge->next->next->pair) { - return P_FALSE; + return false; } else if (pair && !pair->next->pair && !pair->next->next->pair) { - return P_FALSE; + return false; } } /* avoid merging two boundaries (oldv and keepv are on the 'other side' of * the chart) */ else if (!p_vert_interior(oldv) && !p_vert_interior(keepv)) { - return P_FALSE; + return false; } - return P_TRUE; + return true; } -static PBool p_collapse_normal_flipped(float *v1, float *v2, float *vold, float *vnew) +static bool p_collapse_normal_flipped(float *v1, float *v2, float *vold, float *vnew) { float nold[3], nnew[3], sub1[3], sub2[3]; @@ -1923,7 +1887,7 @@ static PBool p_collapse_normal_flipped(float *v1, float *v2, float *vold, float return (dot_v3v3(nold, nnew) <= 0.0f); } -static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair) +static bool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair) { PVert *oldv, *keepv; PEdge *e; @@ -1950,7 +1914,7 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair) } if (p_collapse_normal_flipped(v1->co, v2->co, oldv->co, keepv->co)) { - return P_FALSE; + return false; } a[0] = angle; @@ -1967,10 +1931,10 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair) for (i = 0; i < 3; i++) { if ((b[i] < a[i]) && (b[i] < minangle)) { - return P_FALSE; + return false; } else if ((b[i] > a[i]) && (b[i] > maxangle)) { - return P_FALSE; + return false; } } @@ -1980,7 +1944,7 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair) if (p_vert_interior(oldv)) { /* HLSCM criterion: angular defect smaller than threshold. */ if (fabsf(angulardefect) > (float)(M_PI * 30.0 / 180.0)) { - return P_FALSE; + return false; } } else { @@ -1989,27 +1953,27 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair) /* ABF++ criterion 2: avoid collapsing verts inwards. */ if (p_vert_interior(keepv)) { - return P_FALSE; + return false; } /* Don't collapse significant boundary changes. */ angle = p_vec_angle(v1->co, oldv->co, v2->co); if (angle < (M_PI * 160.0 / 180.0)) { - return P_FALSE; + return false; } } - return P_TRUE; + return true; } -static PBool p_collapse_allowed(PEdge *edge, PEdge *pair) +static bool p_collapse_allowed(PEdge *edge, PEdge *pair) { PVert *oldv, *keepv; p_collapsing_verts(edge, pair, &oldv, &keepv); if (oldv->flag & PVERT_PIN) { - return P_FALSE; + return false; } return (p_collapse_allowed_topologic(edge, pair) && p_collapse_allowed_geometric(edge, pair)); @@ -2572,21 +2536,17 @@ static float p_abf_compute_gradient(PAbfSystem *sys, PChart *chart) return norm; } -static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart) +static bool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart) { - PFace *f; - PEdge *e; - int i, j, ninterior = sys->ninterior, nvar = 2 * sys->ninterior; - PBool success; - LinearSolver *context; - - context = EIG_linear_solver_new(0, nvar, 1); + int ninterior = sys->ninterior; + int nvar = 2 * ninterior; + LinearSolver *context = EIG_linear_solver_new(0, nvar, 1); - for (i = 0; i < nvar; i++) { + for (int i = 0; i < nvar; i++) { EIG_linear_solver_right_hand_side_add(context, 0, i, sys->bInterior[i]); } - for (f = chart->faces; f; f = f->nextlink) { + for (PFace *f = chart->faces; f; f = f->nextlink) { float wi1, wi2, wi3, b, si, beta[3], j2[3][3], W[3][3]; float row1[6], row2[6], row3[6]; int vid[6]; @@ -2691,14 +2651,14 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart) row3[5] = j2[0][2] * W[2][0] + j2[1][2] * W[2][1]; } - for (i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) { int r = vid[i]; if (r == -1) { continue; } - for (j = 0; j < 6; j++) { + for (int j = 0; j < 6; j++) { int c = vid[j]; if (c == -1) { @@ -2729,10 +2689,10 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart) } } - success = EIG_linear_solver_solve(context); + bool success = EIG_linear_solver_solve(context); if (success) { - for (f = chart->faces; f; f = f->nextlink) { + for (PFace *f = chart->faces; f; f = f->nextlink) { float dlambda1, pre[3], dalpha; PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert; @@ -2778,7 +2738,7 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart) sys->alpha[e3->u.id] += dalpha / sys->weight[e3->u.id] - pre[2]; /* clamp */ - e = f->edge; + PEdge *e = f->edge; do { if (sys->alpha[e->u.id] > (float)M_PI) { sys->alpha[e->u.id] = (float)M_PI; @@ -2789,7 +2749,7 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart) } while (e != f->edge); } - for (i = 0; i < ninterior; i++) { + for (int i = 0; i < ninterior; i++) { sys->lambdaPlanar[i] += (float)EIG_linear_solver_variable_get(context, 0, i); sys->lambdaLength[i] += (float)EIG_linear_solver_variable_get(context, 0, ninterior + i); } @@ -2800,7 +2760,7 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart) return success; } -static PBool p_chart_abf_solve(PChart *chart) +static bool p_chart_abf_solve(PChart *chart) { PVert *v; PFace *f; @@ -2911,7 +2871,7 @@ static PBool p_chart_abf_solve(PChart *chart) if (!p_abf_matrix_invert(&sys, chart)) { param_warning("ABF failed to invert matrix"); p_abf_free_system(&sys); - return P_FALSE; + return false; } p_abf_compute_sines(&sys); @@ -2920,14 +2880,14 @@ static PBool p_chart_abf_solve(PChart *chart) if (i == ABF_MAX_ITER) { param_warning("ABF maximum iterations reached"); p_abf_free_system(&sys); - return P_FALSE; + return false; } } chart->u.lscm.abf_alpha = MEM_dupallocN(sys.alpha); p_abf_free_system(&sys); - return P_TRUE; + return true; } /* Least Squares Conformal Maps */ @@ -2983,7 +2943,7 @@ static void p_chart_pin_positions(PChart *chart, PVert **pin1, PVert **pin2) } } -static PBool p_chart_symmetry_pins(PChart *chart, PEdge *outer, PVert **pin1, PVert **pin2) +static bool p_chart_symmetry_pins(PChart *chart, PEdge *outer, PVert **pin1, PVert **pin2) { PEdge *be, *lastbe = NULL, *maxe1 = NULL, *maxe2 = NULL, *be1, *be2; PEdge *cure = NULL, *firste1 = NULL, *firste2 = NULL, *nextbe; @@ -3044,7 +3004,7 @@ static PBool p_chart_symmetry_pins(PChart *chart, PEdge *outer, PVert **pin1, PV } if (!maxe1 || !maxe2 || (maxlen < 0.5f * totlen)) { - return P_FALSE; + return false; } /* find pin1 in the split vertices */ @@ -3144,10 +3104,10 @@ static void p_chart_lscm_load_solution(PChart *chart) } } -static void p_chart_lscm_begin(PChart *chart, PBool live, PBool abf) +static void p_chart_lscm_begin(PChart *chart, bool live, bool abf) { PVert *v, *pin1, *pin2; - PBool select = P_FALSE, deselect = P_FALSE; + bool select = false, deselect = false; int npins = 0, id = 0; /* give vertices matrix indices and count pins */ @@ -3155,12 +3115,12 @@ static void p_chart_lscm_begin(PChart *chart, PBool live, PBool abf) if (v->flag & PVERT_PIN) { npins++; if (v->flag & PVERT_SELECT) { - select = P_TRUE; + select = true; } } if (!(v->flag & PVERT_SELECT)) { - deselect = P_TRUE; + deselect = true; } } @@ -3213,7 +3173,7 @@ static void p_chart_lscm_begin(PChart *chart, PBool live, PBool abf) } } -static PBool p_chart_lscm_solve(ParamHandle *handle, PChart *chart) +static bool p_chart_lscm_solve(ParamHandle *handle, PChart *chart) { LinearSolver *context = chart->u.lscm.context; PVert *v, *pin1 = chart->u.lscm.pin1, *pin2 = chart->u.lscm.pin2; @@ -3350,7 +3310,7 @@ static PBool p_chart_lscm_solve(ParamHandle *handle, PChart *chart) if (EIG_linear_solver_solve(context)) { p_chart_lscm_load_solution(chart); - return P_TRUE; + return true; } for (v = chart->verts; v; v = v->nextlink) { @@ -3358,7 +3318,7 @@ static PBool p_chart_lscm_solve(ParamHandle *handle, PChart *chart) v->uv[1] = 0.0f; } - return P_FALSE; + return false; } static void p_chart_lscm_transform_single_pin(PChart *chart) @@ -3570,7 +3530,7 @@ static int p_compare_geometric_uv(const void *a, const void *b) return 1; } -static PBool p_chart_convex_hull(PChart *chart, PVert ***r_verts, int *r_nverts, int *r_right) +static bool p_chart_convex_hull(PChart *chart, PVert ***r_verts, int *r_nverts, int *r_right) { /* Graham algorithm, taken from: * http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/117225 */ @@ -3582,7 +3542,7 @@ static PBool p_chart_convex_hull(PChart *chart, PVert ***r_verts, int *r_nverts, p_chart_boundaries(chart, NULL, &be); if (!be) { - return P_FALSE; + return false; } e = be; @@ -3636,7 +3596,7 @@ static PBool p_chart_convex_hull(PChart *chart, PVert ***r_verts, int *r_nverts, MEM_freeN(U); MEM_freeN(L); - return P_TRUE; + return true; } static float p_rectangle_area(float *p1, float *dir, float *p2, float *p3, float *p4) @@ -3819,545 +3779,6 @@ static void p_chart_rotate_fit_aabb(PChart *chart) } } -/* Area Smoothing */ - -/* 2d BSP tree for inverse mapping - that's a bit silly. */ - -typedef struct SmoothTriangle { - float co1[2], co2[2], co3[2]; - float oco1[2], oco2[2], oco3[2]; -} SmoothTriangle; - -typedef struct SmoothNode { - struct SmoothNode *c1, *c2; - SmoothTriangle **tri; - float split; - int axis, ntri; -} SmoothNode; - -static void p_barycentric_2d( - const float v1[2], const float v2[2], const float v3[2], const float p[2], float b[3]) -{ - float a[2], c[2], h[2], div; - - a[0] = v2[0] - v1[0]; - a[1] = v2[1] - v1[1]; - c[0] = v3[0] - v1[0]; - c[1] = v3[1] - v1[1]; - - div = a[0] * c[1] - a[1] * c[0]; - - if (div == 0.0f) { - b[0] = 1.0f / 3.0f; - b[1] = 1.0f / 3.0f; - b[2] = 1.0f / 3.0f; - } - else { - h[0] = p[0] - v1[0]; - h[1] = p[1] - v1[1]; - - div = 1.0f / div; - - b[1] = (h[0] * c[1] - h[1] * c[0]) * div; - b[2] = (a[0] * h[1] - a[1] * h[0]) * div; - b[0] = 1.0f - b[1] - b[2]; - } -} - -static PBool p_triangle_inside(SmoothTriangle *t, float co[2]) -{ - float b[3]; - - p_barycentric_2d(t->co1, t->co2, t->co3, co, b); - - if ((b[0] >= 0.0f) && (b[1] >= 0.0f) && (b[2] >= 0.0f)) { - co[0] = t->oco1[0] * b[0] + t->oco2[0] * b[1] + t->oco3[0] * b[2]; - co[1] = t->oco1[1] * b[0] + t->oco2[1] * b[1] + t->oco3[1] * b[2]; - return P_TRUE; - } - - return P_FALSE; -} - -static SmoothNode *p_node_new( - MemArena *arena, SmoothTriangle **tri, int ntri, float *bmin, float *bmax, int depth) -{ - SmoothNode *node = BLI_memarena_alloc(arena, sizeof(*node)); - int axis, i, t1size = 0, t2size = 0; - float split, /* mi, */ /* UNUSED */ mx; - SmoothTriangle **t1, **t2, *t; - - node->tri = tri; - node->ntri = ntri; - - if (ntri <= 10 || depth >= 15) { - return node; - } - - t1 = MEM_mallocN(sizeof(*t1) * ntri, "PNodeTri1"); - t2 = MEM_mallocN(sizeof(*t2) * ntri, "PNodeTri1"); - - axis = (bmax[0] - bmin[0] > bmax[1] - bmin[1]) ? 0 : 1; - split = 0.5f * (bmin[axis] + bmax[axis]); - - for (i = 0; i < ntri; i++) { - t = tri[i]; - - if ((t->co1[axis] <= split) || (t->co2[axis] <= split) || (t->co3[axis] <= split)) { - t1[t1size] = t; - t1size++; - } - if ((t->co1[axis] >= split) || (t->co2[axis] >= split) || (t->co3[axis] >= split)) { - t2[t2size] = t; - t2size++; - } - } - - if ((t1size == t2size) && (t1size == ntri)) { - MEM_freeN(t1); - MEM_freeN(t2); - return node; - } - - node->tri = NULL; - node->ntri = 0; - MEM_freeN(tri); - - node->axis = axis; - node->split = split; - - /* mi = bmin[axis]; */ /* UNUSED */ - mx = bmax[axis]; - bmax[axis] = split; - node->c1 = p_node_new(arena, t1, t1size, bmin, bmax, depth + 1); - - bmin[axis] = bmax[axis]; - bmax[axis] = mx; - node->c2 = p_node_new(arena, t2, t2size, bmin, bmax, depth + 1); - - return node; -} - -static void p_node_delete(SmoothNode *node) -{ - if (node->c1) { - p_node_delete(node->c1); - } - if (node->c2) { - p_node_delete(node->c2); - } - if (node->tri) { - MEM_freeN(node->tri); - } -} - -static PBool p_node_intersect(SmoothNode *node, float co[2]) -{ - int i; - - if (node->tri) { - for (i = 0; i < node->ntri; i++) { - if (p_triangle_inside(node->tri[i], co)) { - return P_TRUE; - } - } - - return P_FALSE; - } - - if (co[node->axis] < node->split) { - return p_node_intersect(node->c1, co); - } - return p_node_intersect(node->c2, co); -} - -/* smoothing */ - -static int p_compare_float(const void *a_, const void *b_) -{ - const float a = *(const float *)a_; - const float b = *(const float *)b_; - - if (a < b) { - return -1; - } - if (a == b) { - return 0; - } - return 1; -} - -static float p_smooth_median_edge_length(PChart *chart) -{ - PEdge *e; - float *lengths = MEM_mallocN(sizeof(chart->edges) * chart->nedges, "PMedianLength"); - float median; - int i; - - /* ok, so I'm lazy */ - for (i = 0, e = chart->edges; e; e = e->nextlink, i++) { - lengths[i] = p_edge_length(e); - } - - qsort(lengths, i, sizeof(float), p_compare_float); - - median = lengths[i / 2]; - MEM_freeN(lengths); - - return median; -} - -static float p_smooth_distortion(PEdge *e, float avg2d, float avg3d) -{ - float len2d = p_edge_uv_length(e) * avg3d; - float len3d = p_edge_length(e) * avg2d; - - return (len3d == 0.0f) ? 0.0f : len2d / len3d; -} - -static void p_smooth(PChart *chart) -{ - PEdge *e; - PVert *v; - PFace *f; - int j, it2, maxiter2, it; - int nedges = chart->nedges, nwheel, gridx, gridy; - int edgesx, edgesy, nsize, esize, i, x, y, maxiter; - float minv[2], maxv[2], median, invmedian, avglen2d, avglen3d; - float center[2], dx, dy, *nodes, dlimit, d, *oldnodesx, *oldnodesy; - float *nodesx, *nodesy, *hedges, *vedges, climit, moved, padding; - SmoothTriangle *triangles, *t, *t2, **tri, **trip; - SmoothNode *root; - MemArena *arena; - - if (nedges == 0) { - return; - } - - p_chart_uv_bbox(chart, minv, maxv); - median = p_smooth_median_edge_length(chart) * 0.10f; - - if (median == 0.0f) { - return; - } - - invmedian = 1.0f / median; - - /* compute edge distortion */ - avglen2d = avglen3d = 0.0; - - for (e = chart->edges; e; e = e->nextlink) { - avglen2d += p_edge_uv_length(e); - avglen3d += p_edge_length(e); - } - - avglen2d /= nedges; - avglen3d /= nedges; - - for (v = chart->verts; v; v = v->nextlink) { - v->u.distortion = 0.0; - nwheel = 0; - - e = v->edge; - do { - v->u.distortion += p_smooth_distortion(e, avglen2d, avglen3d); - nwheel++; - - e = e->next->next->pair; - } while (e && (e != v->edge)); - - v->u.distortion /= nwheel; - } - - /* need to do excessive grid size checking still */ - center[0] = 0.5f * (minv[0] + maxv[0]); - center[1] = 0.5f * (minv[1] + maxv[1]); - - dx = 0.5f * (maxv[0] - minv[0]); - dy = 0.5f * (maxv[1] - minv[1]); - - padding = 0.15f; - dx += padding * dx + 2.0f * median; - dy += padding * dy + 2.0f * median; - - gridx = (int)(dx * invmedian); - gridy = (int)(dy * invmedian); - - minv[0] = center[0] - median * gridx; - minv[1] = center[1] - median * gridy; - maxv[0] = center[0] + median * gridx; - maxv[1] = center[1] + median * gridy; - - /* create grid */ - gridx = gridx * 2 + 1; - gridy = gridy * 2 + 1; - - if ((gridx <= 2) || (gridy <= 2)) { - return; - } - - edgesx = gridx - 1; - edgesy = gridy - 1; - nsize = gridx * gridy; - esize = edgesx * edgesy; - - nodes = MEM_mallocN(sizeof(float) * nsize, "PSmoothNodes"); - nodesx = MEM_mallocN(sizeof(float) * nsize, "PSmoothNodesX"); - nodesy = MEM_mallocN(sizeof(float) * nsize, "PSmoothNodesY"); - oldnodesx = MEM_mallocN(sizeof(float) * nsize, "PSmoothOldNodesX"); - oldnodesy = MEM_mallocN(sizeof(float) * nsize, "PSmoothOldNodesY"); - hedges = MEM_mallocN(sizeof(float) * esize, "PSmoothHEdges"); - vedges = MEM_mallocN(sizeof(float) * esize, "PSmoothVEdges"); - - if (!nodes || !nodesx || !nodesy || !oldnodesx || !oldnodesy || !hedges || !vedges) { - if (nodes) { - MEM_freeN(nodes); - } - if (nodesx) { - MEM_freeN(nodesx); - } - if (nodesy) { - MEM_freeN(nodesy); - } - if (oldnodesx) { - MEM_freeN(oldnodesx); - } - if (oldnodesy) { - MEM_freeN(oldnodesy); - } - if (hedges) { - MEM_freeN(hedges); - } - if (vedges) { - MEM_freeN(vedges); - } - - // printf("Not enough memory for area smoothing grid"); - return; - } - - for (x = 0; x < gridx; x++) { - for (y = 0; y < gridy; y++) { - i = x + y * gridx; - - nodesx[i] = minv[0] + median * x; - nodesy[i] = minv[1] + median * y; - - nodes[i] = 1.0f; - } - } - - /* embed in grid */ - for (f = chart->faces; f; f = f->nextlink) { - PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; - float fmin[2], fmax[2]; - int bx1, by1, bx2, by2; - - INIT_MINMAX2(fmin, fmax); - - minmax_v2v2_v2(fmin, fmax, e1->vert->uv); - minmax_v2v2_v2(fmin, fmax, e2->vert->uv); - minmax_v2v2_v2(fmin, fmax, e3->vert->uv); - - bx1 = (int)((fmin[0] - minv[0]) * invmedian); - by1 = (int)((fmin[1] - minv[1]) * invmedian); - bx2 = (int)((fmax[0] - minv[0]) * invmedian + 2); - by2 = (int)((fmax[1] - minv[1]) * invmedian + 2); - - for (x = bx1; x < bx2; x++) { - for (y = by1; y < by2; y++) { - float p[2], b[3]; - - i = x + y * gridx; - - p[0] = nodesx[i]; - p[1] = nodesy[i]; - - p_barycentric_2d(e1->vert->uv, e2->vert->uv, e3->vert->uv, p, b); - - if ((b[0] > 0.0f) && (b[1] > 0.0f) && (b[2] > 0.0f)) { - nodes[i] = e1->vert->u.distortion * b[0]; - nodes[i] += e2->vert->u.distortion * b[1]; - nodes[i] += e3->vert->u.distortion * b[2]; - } - } - } - } - - /* smooth the grid */ - maxiter = 10; - climit = 0.00001f * nsize; - - for (it = 0; it < maxiter; it++) { - moved = 0.0f; - - for (x = 0; x < edgesx; x++) { - for (y = 0; y < edgesy; y++) { - i = x + y * gridx; - j = x + y * edgesx; - - hedges[j] = (nodes[i] + nodes[i + 1]) * 0.5f; - vedges[j] = (nodes[i] + nodes[i + gridx]) * 0.5f; - - /* we do *inverse* mapping */ - hedges[j] = 1.0f / hedges[j]; - vedges[j] = 1.0f / vedges[j]; - } - } - - maxiter2 = 50; - dlimit = 0.0001f; - - for (it2 = 0; it2 < maxiter2; it2++) { - d = 0.0f; - - memcpy(oldnodesx, nodesx, sizeof(float) * nsize); - memcpy(oldnodesy, nodesy, sizeof(float) * nsize); - - for (x = 1; x < gridx - 1; x++) { - for (y = 1; y < gridy - 1; y++) { - float p[2], oldp[2], sum1, sum2, diff[2], length; - - i = x + gridx * y; - j = x + edgesx * y; - - oldp[0] = oldnodesx[i]; - oldp[1] = oldnodesy[i]; - - sum1 = hedges[j - 1] * oldnodesx[i - 1]; - sum1 += hedges[j] * oldnodesx[i + 1]; - sum1 += vedges[j - edgesx] * oldnodesx[i - gridx]; - sum1 += vedges[j] * oldnodesx[i + gridx]; - - sum2 = hedges[j - 1]; - sum2 += hedges[j]; - sum2 += vedges[j - edgesx]; - sum2 += vedges[j]; - - nodesx[i] = sum1 / sum2; - - sum1 = hedges[j - 1] * oldnodesy[i - 1]; - sum1 += hedges[j] * oldnodesy[i + 1]; - sum1 += vedges[j - edgesx] * oldnodesy[i - gridx]; - sum1 += vedges[j] * oldnodesy[i + gridx]; - - nodesy[i] = sum1 / sum2; - - p[0] = nodesx[i]; - p[1] = nodesy[i]; - - diff[0] = p[0] - oldp[0]; - diff[1] = p[1] - oldp[1]; - - length = len_v2(diff); - d = max_ff(d, length); - moved += length; - } - } - - if (d < dlimit) { - break; - } - } - - if (moved < climit) { - break; - } - } - - MEM_freeN(oldnodesx); - MEM_freeN(oldnodesy); - MEM_freeN(hedges); - MEM_freeN(vedges); - - /* Create BSP. */ - t = triangles = MEM_mallocN(sizeof(SmoothTriangle) * esize * 2, "PSmoothTris"); - trip = tri = MEM_mallocN(sizeof(SmoothTriangle *) * esize * 2, "PSmoothTriP"); - - if (!triangles || !tri) { - MEM_freeN(nodes); - MEM_freeN(nodesx); - MEM_freeN(nodesy); - - if (triangles) { - MEM_freeN(triangles); - } - if (tri) { - MEM_freeN(tri); - } - - // printf("Not enough memory for area smoothing grid"); - return; - } - - for (x = 0; x < edgesx; x++) { - for (y = 0; y < edgesy; y++) { - i = x + y * gridx; - - t->co1[0] = nodesx[i]; - t->co1[1] = nodesy[i]; - - t->co2[0] = nodesx[i + 1]; - t->co2[1] = nodesy[i + 1]; - - t->co3[0] = nodesx[i + gridx]; - t->co3[1] = nodesy[i + gridx]; - - t->oco1[0] = minv[0] + x * median; - t->oco1[1] = minv[1] + y * median; - - t->oco2[0] = minv[0] + (x + 1) * median; - t->oco2[1] = minv[1] + y * median; - - t->oco3[0] = minv[0] + x * median; - t->oco3[1] = minv[1] + (y + 1) * median; - - t2 = t + 1; - - t2->co1[0] = nodesx[i + gridx + 1]; - t2->co1[1] = nodesy[i + gridx + 1]; - - t2->oco1[0] = minv[0] + (x + 1) * median; - t2->oco1[1] = minv[1] + (y + 1) * median; - - t2->co2[0] = t->co2[0]; - t2->co2[1] = t->co2[1]; - t2->oco2[0] = t->oco2[0]; - t2->oco2[1] = t->oco2[1]; - - t2->co3[0] = t->co3[0]; - t2->co3[1] = t->co3[1]; - t2->oco3[0] = t->oco3[0]; - t2->oco3[1] = t->oco3[1]; - - *trip = t; - trip++; - t++; - *trip = t; - trip++; - t++; - } - } - - MEM_freeN(nodes); - MEM_freeN(nodesx); - MEM_freeN(nodesy); - - arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "param smooth arena"); - root = p_node_new(arena, tri, esize * 2, minv, maxv, 0); - - for (v = chart->verts; v; v = v->nextlink) { - if (!p_node_intersect(root, v->uv)) { - param_warning("area smoothing error: couldn't find mapping triangle\n"); - } - } - - p_node_delete(root); - BLI_memarena_free(arena); - - MEM_freeN(triangles); -} - /* Exported */ ParamHandle *GEO_uv_parametrizer_construct_begin(void) @@ -4415,13 +3836,13 @@ void GEO_uv_parametrizer_delete(ParamHandle *phandle) } static void p_add_ngon(ParamHandle *handle, - ParamKey key, - int nverts, - ParamKey *vkeys, - float **co, - float **uv, - ParamBool *pin, - ParamBool *select) + const ParamKey key, + const int nverts, + const ParamKey *vkeys, + const float **co, + float **uv, /* Output will eventually be written to `uv`. */ + const bool *pin, + const bool *select) { /* Allocate memory for polyfill. */ MemArena *arena = handle->polyfill_arena; @@ -4463,11 +3884,11 @@ static void p_add_ngon(ParamHandle *handle, uint v1 = tri[1]; uint v2 = tri[2]; - ParamKey tri_vkeys[3] = {vkeys[v0], vkeys[v1], vkeys[v2]}; - float *tri_co[3] = {co[v0], co[v1], co[v2]}; + const ParamKey tri_vkeys[3] = {vkeys[v0], vkeys[v1], vkeys[v2]}; + const float *tri_co[3] = {co[v0], co[v1], co[v2]}; float *tri_uv[3] = {uv[v0], uv[v1], uv[v2]}; - ParamBool tri_pin[3] = {pin[v0], pin[v1], pin[v2]}; - ParamBool tri_select[3] = {select[v0], select[v1], select[v2]}; + bool tri_pin[3] = {pin[v0], pin[v1], pin[v2]}; + bool tri_select[3] = {select[v0], select[v1], select[v2]}; GEO_uv_parametrizer_face_add(handle, key, 3, tri_vkeys, tri_co, tri_uv, tri_pin, tri_select); } @@ -4476,13 +3897,13 @@ static void p_add_ngon(ParamHandle *handle, } void GEO_uv_parametrizer_face_add(ParamHandle *phandle, - ParamKey key, - int nverts, - ParamKey *vkeys, - float *co[4], - float *uv[4], - ParamBool *pin, - ParamBool *select) + const ParamKey key, + const int nverts, + const ParamKey *vkeys, + const float **co, + float **uv, + const bool *pin, + const bool *select) { param_assert(phash_lookup(phandle->hash_faces, key) == NULL); param_assert(phandle->state == PHANDLE_STATE_ALLOCATED); @@ -4522,8 +3943,8 @@ void GEO_uv_parametrizer_edge_set_seam(ParamHandle *phandle, ParamKey *vkeys) } void GEO_uv_parametrizer_construct_end(ParamHandle *phandle, - ParamBool fill, - ParamBool topology_from_uvs, + bool fill, + bool topology_from_uvs, int *count_fail) { PChart *chart = phandle->construction_chart; @@ -4532,7 +3953,7 @@ void GEO_uv_parametrizer_construct_end(ParamHandle *phandle, param_assert(phandle->state == PHANDLE_STATE_ALLOCATED); - phandle->ncharts = p_connect_pairs(phandle, (PBool)topology_from_uvs); + phandle->ncharts = p_connect_pairs(phandle, topology_from_uvs); phandle->charts = p_split_charts(phandle, chart, phandle->ncharts); p_chart_delete(phandle->construction_chart); @@ -4574,7 +3995,7 @@ void GEO_uv_parametrizer_construct_end(ParamHandle *phandle, phandle->state = PHANDLE_STATE_CONSTRUCTED; } -void GEO_uv_parametrizer_lscm_begin(ParamHandle *phandle, ParamBool live, ParamBool abf) +void GEO_uv_parametrizer_lscm_begin(ParamHandle *phandle, bool live, bool abf) { PFace *f; int i; @@ -4586,7 +4007,7 @@ void GEO_uv_parametrizer_lscm_begin(ParamHandle *phandle, ParamBool live, ParamB for (f = phandle->charts[i]->faces; f; f = f->nextlink) { p_face_backup_uvs(f); } - p_chart_lscm_begin(phandle->charts[i], (PBool)live, (PBool)abf); + p_chart_lscm_begin(phandle->charts[i], live, abf); } } @@ -4601,7 +4022,7 @@ void GEO_uv_parametrizer_lscm_solve(ParamHandle *phandle, int *count_changed, in chart = phandle->charts[i]; if (chart->u.lscm.context) { - const PBool result = p_chart_lscm_solve(phandle, chart); + const bool result = p_chart_lscm_solve(phandle, chart); if (result && !(chart->flag & PCHART_HAS_PINS)) { p_chart_rotate_minimum_area(chart); @@ -4702,24 +4123,6 @@ void GEO_uv_parametrizer_stretch_end(ParamHandle *phandle) phandle->rng = NULL; } -void GEO_uv_parametrizer_smooth_area(ParamHandle *phandle) -{ - int i; - - param_assert(phandle->state == PHANDLE_STATE_CONSTRUCTED); - - for (i = 0; i < phandle->ncharts; i++) { - PChart *chart = phandle->charts[i]; - PVert *v; - - for (v = chart->verts; v; v = v->nextlink) { - v->flag &= ~PVERT_PIN; - } - - p_smooth(chart); - } -} - /* don't pack, just rotate (used for better packing) */ static void GEO_uv_parametrizer_pack_rotate(ParamHandle *phandle, bool ignore_pinned) { diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h index e7301b4d910..73423d9a8ee 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h @@ -49,5 +49,5 @@ typedef void (*gpBakeCb)(struct GpencilModifierData *md_, void generic_bake_deform_stroke(struct Depsgraph *depsgraph, struct GpencilModifierData *md, struct Object *ob, - const bool retime, + bool retime, gpBakeCb bake_cb); diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index ad3e1b5d7f2..16b9fcbbdd7 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -236,6 +236,9 @@ typedef struct LineartRenderBuffer { ListBase line_buffer_pointers; ListBase triangle_buffer_pointers; + LineartElementLinkNode *isect_scheduled_up_to; + int isect_scheduled_up_to_index; + /** This one's memory is not from main pool and is free()ed after culling stage. */ ListBase triangle_adjacent_pointers; @@ -429,15 +432,18 @@ typedef struct LineartBoundingArea { /** 1,2,3,4 quadrant */ struct LineartBoundingArea *child; + SpinLock lock; + ListBase lp; ListBase rp; ListBase up; ListBase bp; - uint16_t triangle_count; - uint16_t max_triangle_count; - uint16_t line_count; - uint16_t max_line_count; + uint32_t triangle_count; + uint32_t max_triangle_count; + uint32_t line_count; + uint32_t max_line_count; + uint32_t user_count; /* Use array for speeding up multiple accesses. */ struct LineartTriangle **linked_triangles; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index 016b70cedb0..621531d29e3 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -52,6 +52,36 @@ #include "lineart_intern.h" +typedef struct LineartIsecSingle { + float v1[3], v2[3]; + LineartTriangle *tri1, *tri2; +} LineartIsecSingle; + +typedef struct LineartIsecThread { + int thread_id; + + /* Scheduled work range. */ + LineartElementLinkNode *pending_from; + LineartElementLinkNode *pending_to; + int index_from; + int index_to; + + /* Thread intersection result data. */ + LineartIsecSingle *array; + int current; + int max; + int count_test; + + /* For individual thread reference.*/ + LineartRenderBuffer *rb; +} LineartIsecThread; + +typedef struct LineartIsecData { + LineartRenderBuffer *rb; + LineartIsecThread *threads; + int thread_count; +} LineartIsecData; + static LineartBoundingArea *lineart_edge_first_bounding_area(LineartRenderBuffer *rb, LineartEdge *e); @@ -76,14 +106,6 @@ static bool lineart_get_edge_bounding_areas(LineartRenderBuffer *rb, int *colbegin, int *colend); -static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb, - LineartBoundingArea *root_ba, - LineartTriangle *tri, - double *LRUB, - int recursive, - int recursive_level, - bool do_intersection); - static bool lineart_triangle_edge_image_space_occlusion(SpinLock *spl, const LineartTriangle *tri, const LineartEdge *e, @@ -99,6 +121,19 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *spl, static void lineart_add_edge_to_array(LineartPendingEdges *pe, LineartEdge *e); +static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb, + LineartBoundingArea *root_ba, + LineartTriangle *tri, + double *LRUB, + int recursive, + int recursive_level, + bool do_intersection, + struct LineartIsecThread *th); + +static void lineart_free_bounding_area_memory(LineartBoundingArea *ba, bool recursive); + +static void lineart_free_bounding_area_memories(LineartRenderBuffer *rb); + static LineartCache *lineart_init_cache(void); static void lineart_discard_segment(LineartRenderBuffer *rb, LineartEdgeSegment *es) @@ -312,29 +347,14 @@ BLI_INLINE bool lineart_occlusion_is_adjacent_intersection(LineartEdge *e, Linea (v2->base.flag && v2->intersecting_with == tri)); } -static void lineart_bounding_area_triangle_add(LineartRenderBuffer *rb, - LineartBoundingArea *ba, - LineartTriangle *tri) -{ /* In case of too many triangles concentrating in one point, do not add anymore, these triangles - * will be either narrower than a single pixel, or will still be added into the list of other - * less dense areas. */ - if (ba->triangle_count >= 65535) { - return; - } - if (ba->triangle_count >= ba->max_triangle_count) { - LineartTriangle **new_array = lineart_mem_acquire( - &rb->render_data_pool, sizeof(LineartTriangle *) * ba->max_triangle_count * 2); - memcpy(new_array, ba->linked_triangles, sizeof(LineartTriangle *) * ba->max_triangle_count); - ba->max_triangle_count *= 2; - ba->linked_triangles = new_array; - } - ba->linked_triangles[ba->triangle_count] = tri; - ba->triangle_count++; +static void lineart_bounding_area_triangle_reallocate(LineartBoundingArea *ba) +{ + ba->max_triangle_count *= 2; + ba->linked_triangles = MEM_recallocN(ba->linked_triangles, + sizeof(LineartTriangle *) * ba->max_triangle_count); } -static void lineart_bounding_area_line_add(LineartRenderBuffer *rb, - LineartBoundingArea *ba, - LineartEdge *e) +static void lineart_bounding_area_line_add(LineartBoundingArea *ba, LineartEdge *e) { /* In case of too many lines concentrating in one point, do not add anymore, these lines will * be either shorter than a single pixel, or will still be added into the list of other less @@ -343,10 +363,11 @@ static void lineart_bounding_area_line_add(LineartRenderBuffer *rb, return; } if (ba->line_count >= ba->max_line_count) { - LineartEdge **new_array = lineart_mem_acquire(&rb->render_data_pool, - sizeof(LineartEdge *) * ba->max_line_count * 2); + LineartEdge **new_array = MEM_mallocN(sizeof(LineartEdge *) * ba->max_line_count * 2, + "new ba_line_array"); memcpy(new_array, ba->linked_lines, sizeof(LineartEdge *) * ba->max_line_count); ba->max_line_count *= 2; + MEM_freeN(ba->linked_lines); ba->linked_lines = new_array; } ba->linked_lines[ba->line_count] = e; @@ -699,6 +720,7 @@ static void lineart_triangle_post(LineartTriangle *tri, LineartTriangle *orig) /* Just re-assign normal and set cull flag. */ copy_v3_v3_db(tri->gn, orig->gn); tri->flags = LRT_CULL_GENERATED; + tri->intersection_mask = orig->intersection_mask; tri->material_mask_bits = orig->material_mask_bits; tri->mat_occlusion = orig->mat_occlusion; } @@ -1679,6 +1701,7 @@ static void lineart_join_loose_edge_arr(LooseEdgeData *loose_data, LooseEdgeData sizeof(MEdge *) * to_be_joined->loose_count); loose_data->loose_count += to_be_joined->loose_count; MEM_freeN(to_be_joined->loose_array); + to_be_joined->loose_array = NULL; } static void lineart_add_loose_edge(LooseEdgeData *loose_data, MEdge *e) @@ -2104,7 +2127,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend elem_link_node->element_count = allocate_la_e; elem_link_node->object_ref = orig_ob; - // Start of the edge/seg arr + /* Start of the edge/seg arr */ LineartEdge *la_edge; LineartEdgeSegment *la_seg; la_edge = la_edge_arr; @@ -2454,31 +2477,35 @@ static void lineart_main_load_geometries( eEvaluationMode eval_mode = DEG_get_mode(depsgraph); bool is_render = eval_mode == DAG_EVAL_RENDER; - FOREACH_SCENE_OBJECT_BEGIN (scene, ob) { + int flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | + DEG_ITER_OBJECT_FLAG_VISIBLE; + + /* Instance duplicated & particles. */ + if (allow_duplicates) { + flags |= DEG_ITER_OBJECT_FLAG_DUPLI; + } + + /* XXX(@Yiming): Temporary solution, this iterator is technically unsafe to use *during* + * depsgraph evaluation, see D14997 for detailed explanations. */ + DEG_OBJECT_ITER_BEGIN (depsgraph, ob, flags) { Object *eval_ob = DEG_get_evaluated_object(depsgraph, ob); if (!eval_ob) { continue; } + /* DEG_OBJECT_ITER_BEGIN will include the instanced mesh of these curve object types, so don't + * load them twice. */ + if (allow_duplicates && ELEM(ob->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) { + continue; + } + if (BKE_object_visibility(eval_ob, eval_mode) & OB_VISIBLE_SELF) { lineart_object_load_single_instance( rb, depsgraph, scene, eval_ob, eval_ob, eval_ob->obmat, is_render, olti, thread_count); } - if (allow_duplicates) { - ListBase *dupli = object_duplilist(depsgraph, scene, eval_ob); - LISTBASE_FOREACH (DupliObject *, dob, dupli) { - if (BKE_object_visibility(eval_ob, eval_mode) & - (OB_VISIBLE_PARTICLES | OB_VISIBLE_INSTANCES)) { - Object *ob_ref = (dob->type & OB_DUPLIPARTS) ? eval_ob : dob->ob; - lineart_object_load_single_instance( - rb, depsgraph, scene, dob->ob, ob_ref, dob->mat, is_render, olti, thread_count); - } - } - free_object_duplilist(dupli); - } } - FOREACH_SCENE_OBJECT_END; + DEG_OBJECT_ITER_END; TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH); @@ -2997,60 +3024,23 @@ static LineartVert *lineart_triangle_share_point(const LineartTriangle *l, return NULL; } -/** - * To save time and prevent overlapping lines when computing intersection lines. - */ -static bool lineart_vert_already_intersected_2v(LineartVertIntersection *vt, - LineartVertIntersection *v1, - LineartVertIntersection *v2) -{ - return ((vt->isec1 == v1->base.index && vt->isec2 == v2->base.index) || - (vt->isec2 == v2->base.index && vt->isec1 == v1->base.index)); -} - -static void lineart_vert_set_intersection_2v(LineartVert *vt, LineartVert *v1, LineartVert *v2) -{ - LineartVertIntersection *irv = (LineartVertIntersection *)vt; - irv->isec1 = v1->index; - irv->isec2 = v2->index; -} - -/** - * This tests a triangle against a virtual line represented by `v1---v2`. - * The vertices returned after repeated calls to this function - * is then used to create a triangle/triangle intersection line. - */ -static LineartVert *lineart_triangle_2v_intersection_test(LineartRenderBuffer *rb, - LineartVert *v1, - LineartVert *v2, - LineartTriangle *tri, - LineartTriangle *testing, - LineartVert *last) +static bool lineart_triangle_2v_intersection_math( + LineartVert *v1, LineartVert *v2, LineartTriangle *t2, double *last, double *rv) { double Lv[3]; double Rv[3]; double dot_l, dot_r; - LineartVert *result; double gloc[3]; LineartVert *l = v1, *r = v2; - for (LinkNode *ln = (void *)testing->intersecting_verts; ln; ln = ln->next) { - LineartVertIntersection *vt = ln->link; - if (vt->intersecting_with == tri && - lineart_vert_already_intersected_2v( - vt, (LineartVertIntersection *)l, (LineartVertIntersection *)r)) { - return (LineartVert *)vt; - } - } + sub_v3_v3v3_db(Lv, l->gloc, t2->v[0]->gloc); + sub_v3_v3v3_db(Rv, r->gloc, t2->v[0]->gloc); - sub_v3_v3v3_db(Lv, l->gloc, testing->v[0]->gloc); - sub_v3_v3v3_db(Rv, r->gloc, testing->v[0]->gloc); - - dot_l = dot_v3v3_db(Lv, testing->gn); - dot_r = dot_v3v3_db(Rv, testing->gn); + dot_l = dot_v3v3_db(Lv, t2->gn); + dot_r = dot_v3v3_db(Rv, t2->gn); if (dot_l * dot_r > 0 || (!dot_l && !dot_r)) { - return 0; + return false; } dot_l = fabs(dot_l); @@ -3060,209 +3050,213 @@ static LineartVert *lineart_triangle_2v_intersection_test(LineartRenderBuffer *r /* Due to precision issue, we might end up with the same point as the one we already detected. */ - if (last && LRT_DOUBLE_CLOSE_ENOUGH(last->gloc[0], gloc[0]) && - LRT_DOUBLE_CLOSE_ENOUGH(last->gloc[1], gloc[1]) && - LRT_DOUBLE_CLOSE_ENOUGH(last->gloc[2], gloc[2])) { - return NULL; + if (last && LRT_DOUBLE_CLOSE_ENOUGH(last[0], gloc[0]) && + LRT_DOUBLE_CLOSE_ENOUGH(last[1], gloc[1]) && LRT_DOUBLE_CLOSE_ENOUGH(last[2], gloc[2])) { + return false; } - if (!(lineart_point_inside_triangle3d( - gloc, testing->v[0]->gloc, testing->v[1]->gloc, testing->v[2]->gloc))) { - return NULL; + if (!(lineart_point_inside_triangle3d(gloc, t2->v[0]->gloc, t2->v[1]->gloc, t2->v[2]->gloc))) { + return false; } - /* This is an intersection vert, the size is bigger than LineartVert, - * allocated separately. */ - result = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartVertIntersection)); - - /* Indicate the data structure difference. */ - result->flag = LRT_VERT_HAS_INTERSECTION_DATA; - - copy_v3_v3_db(result->gloc, gloc); - - lineart_prepend_pool(&testing->intersecting_verts, &rb->render_data_pool, result); + copy_v3_v3_db(rv, gloc); - return result; + return true; } -/** - * Test if two triangles intersect. Generates one intersection line if the check succeeds. - */ -static LineartEdge *lineart_triangle_intersect(LineartRenderBuffer *rb, - LineartTriangle *tri, - LineartTriangle *testing) +static bool lineart_triangle_intersect_math(LineartTriangle *tri, + LineartTriangle *t2, + double *v1, + double *v2) { - LineartVert *v1 = 0, *v2 = 0; - LineartVert **next = &v1; - LineartEdge *result; - LineartVert *E0T = 0; - LineartVert *E1T = 0; - LineartVert *E2T = 0; - LineartVert *TE0 = 0; - LineartVert *TE1 = 0; - LineartVert *TE2 = 0; + double *next = v1, *last = NULL; LineartVert *sv1, *sv2; - double cl[3]; - double ZMin, ZMax; - ZMax = rb->far_clip; - ZMin = rb->near_clip; - copy_v3_v3_db(cl, rb->camera_pos); - LineartVert *share = lineart_triangle_share_point(testing, tri); + LineartVert *share = lineart_triangle_share_point(t2, tri); if (share) { /* If triangles have sharing points like `abc` and `acd`, then we only need to detect `bc` * against `acd` or `cd` against `abc`. */ - LineartVert *new_share; lineart_triangle_get_other_verts(tri, share, &sv1, &sv2); - v1 = new_share = lineart_mem_acquire(&rb->render_data_pool, (sizeof(LineartVertIntersection))); - - new_share->flag = LRT_VERT_HAS_INTERSECTION_DATA; + copy_v3_v3_db(v1, share->gloc); - copy_v3_v3_db(new_share->gloc, share->gloc); - - v2 = lineart_triangle_2v_intersection_test(rb, sv1, sv2, tri, testing, 0); - - if (v2 == NULL) { - lineart_triangle_get_other_verts(testing, share, &sv1, &sv2); - v2 = lineart_triangle_2v_intersection_test(rb, sv1, sv2, testing, tri, 0); - if (v2 == NULL) { - return 0; + if (!lineart_triangle_2v_intersection_math(sv1, sv2, t2, 0, v2)) { + lineart_triangle_get_other_verts(t2, share, &sv1, &sv2); + if (lineart_triangle_2v_intersection_math(sv1, sv2, tri, 0, v2)) { + return true; } - lineart_prepend_pool(&testing->intersecting_verts, &rb->render_data_pool, new_share); - } - else { - lineart_prepend_pool(&tri->intersecting_verts, &rb->render_data_pool, new_share); } } else { /* If not sharing any points, then we need to try all the possibilities. */ - E0T = lineart_triangle_2v_intersection_test(rb, tri->v[0], tri->v[1], tri, testing, 0); - if (E0T && (!(*next))) { - (*next) = E0T; - lineart_vert_set_intersection_2v((*next), tri->v[0], tri->v[1]); - next = &v2; - } - E1T = lineart_triangle_2v_intersection_test(rb, tri->v[1], tri->v[2], tri, testing, v1); - if (E1T && (!(*next))) { - (*next) = E1T; - lineart_vert_set_intersection_2v((*next), tri->v[1], tri->v[2]); - next = &v2; - } - if (!(*next)) { - E2T = lineart_triangle_2v_intersection_test(rb, tri->v[2], tri->v[0], tri, testing, v1); - } - if (E2T && (!(*next))) { - (*next) = E2T; - lineart_vert_set_intersection_2v((*next), tri->v[2], tri->v[0]); - next = &v2; + if (lineart_triangle_2v_intersection_math(tri->v[0], tri->v[1], t2, 0, v1)) { + next = v2; + last = v1; } - if (!(*next)) { - TE0 = lineart_triangle_2v_intersection_test( - rb, testing->v[0], testing->v[1], testing, tri, v1); - } - if (TE0 && (!(*next))) { - (*next) = TE0; - lineart_vert_set_intersection_2v((*next), testing->v[0], testing->v[1]); - next = &v2; + if (lineart_triangle_2v_intersection_math(tri->v[1], tri->v[2], t2, last, next)) { + if (last) { + return true; + } + next = v2; + last = v1; } - if (!(*next)) { - TE1 = lineart_triangle_2v_intersection_test( - rb, testing->v[1], testing->v[2], testing, tri, v1); + if (lineart_triangle_2v_intersection_math(tri->v[2], tri->v[0], t2, last, next)) { + if (last) { + return true; + } + next = v2; + last = v1; } - if (TE1 && (!(*next))) { - (*next) = TE1; - lineart_vert_set_intersection_2v((*next), testing->v[1], testing->v[2]); - next = &v2; + + if (lineart_triangle_2v_intersection_math(t2->v[0], t2->v[1], tri, last, next)) { + if (last) { + return true; + } + next = v2; + last = v1; } - if (!(*next)) { - TE2 = lineart_triangle_2v_intersection_test( - rb, testing->v[2], testing->v[0], testing, tri, v1); + if (lineart_triangle_2v_intersection_math(t2->v[1], t2->v[2], tri, last, next)) { + if (last) { + return true; + } + next = v2; + last = v1; } - if (TE2 && (!(*next))) { - (*next) = TE2; - lineart_vert_set_intersection_2v((*next), testing->v[2], testing->v[0]); - next = &v2; + if (lineart_triangle_2v_intersection_math(t2->v[2], t2->v[0], tri, last, next)) { + if (last) { + return true; + } + next = v2; + last = v1; } + } + return false; +} - if (!(*next)) { - return 0; +static void lineart_add_isec_thread(LineartIsecThread *th, + const double *v1, + const double *v2, + LineartTriangle *tri1, + LineartTriangle *tri2) +{ + if (th->current == th->max) { + + LineartIsecSingle *new_array = MEM_mallocN(sizeof(LineartIsecSingle) * th->max * 2, + "LineartIsecSingle"); + memcpy(new_array, th->array, sizeof(LineartIsecSingle) * th->max); + th->max *= 2; + MEM_freeN(th->array); + th->array = new_array; + } + LineartIsecSingle *is = &th->array[th->current]; + copy_v3fl_v3db(is->v1, v1); + copy_v3fl_v3db(is->v2, v2); + is->tri1 = tri1; + is->tri2 = tri2; + th->current++; +} + +#define LRT_ISECT_TRIANGLE_PER_THREAD 4096 + +static bool lineart_schedule_new_triangle_task(LineartIsecThread *th) +{ + LineartRenderBuffer *rb = th->rb; + int remaining = LRT_ISECT_TRIANGLE_PER_THREAD; + + BLI_spin_lock(&rb->lock_task); + LineartElementLinkNode *eln = rb->isect_scheduled_up_to; + + if (!eln) { + BLI_spin_unlock(&rb->lock_task); + return false; + } + + th->pending_from = eln; + th->index_from = rb->isect_scheduled_up_to_index; + + while (remaining > 0 && eln) { + int remaining_this_eln = eln->element_count - rb->isect_scheduled_up_to_index; + int added_count = MIN2(remaining, remaining_this_eln); + remaining -= added_count; + if (remaining || added_count == remaining_this_eln) { + eln = eln->next; + rb->isect_scheduled_up_to = eln; + rb->isect_scheduled_up_to_index = 0; + } + else { + rb->isect_scheduled_up_to_index += added_count; } } - /* The intersection line has been generated only in geometry space, so we need to transform - * them as well. */ - mul_v4_m4v3_db(v1->fbcoord, rb->view_projection, v1->gloc); - mul_v4_m4v3_db(v2->fbcoord, rb->view_projection, v2->gloc); - if (rb->cam_is_persp) { - mul_v3db_db(v1->fbcoord, (1 / v1->fbcoord[3])); - mul_v3db_db(v2->fbcoord, (1 / v2->fbcoord[3])); - } - v1->fbcoord[0] -= rb->shift_x * 2; - v1->fbcoord[1] -= rb->shift_y * 2; - v2->fbcoord[0] -= rb->shift_x * 2; - v2->fbcoord[1] -= rb->shift_y * 2; - - /* This z transformation is not the same as the rest of the part, because the data don't go - * through normal perspective division calls in the pipeline, but this way the 3D result and - * occlusion on the generated line is correct, and we don't really use 2D for viewport stroke - * generation anyway. */ - v1->fbcoord[2] = ZMin * ZMax / (ZMax - fabs(v1->fbcoord[2]) * (ZMax - ZMin)); - v2->fbcoord[2] = ZMin * ZMax / (ZMax - fabs(v2->fbcoord[2]) * (ZMax - ZMin)); - - ((LineartVertIntersection *)v1)->intersecting_with = tri; - ((LineartVertIntersection *)v2)->intersecting_with = testing; - - result = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdge)); - result->v1 = v1; - result->v2 = v2; - result->t1 = tri; - result->t2 = testing; - - LineartEdgeSegment *es = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdgeSegment)); - BLI_addtail(&result->segments, es); - /* Don't need to OR flags right now, just a type mark. */ - result->flags = LRT_EDGE_FLAG_INTERSECTION; - result->intersection_mask = (tri->intersection_mask | testing->intersection_mask); - - lineart_add_edge_to_array(&rb->pending_edges, result); - - return result; + th->pending_to = eln ? eln : rb->triangle_buffer_pointers.last; + th->index_to = rb->isect_scheduled_up_to_index; + + BLI_spin_unlock(&rb->lock_task); + + return true; } -static void lineart_triangle_intersect_in_bounding_area(LineartRenderBuffer *rb, - LineartTriangle *tri, - LineartBoundingArea *ba) +/* This function initializes two things: + * 1) Triangle array scheduling info, for each worker thread to get its chunk from the scheduler. + * 2) Per-thread intersection result array. Does not store actual #LineartEdge, these results will + * be finalized by #lineart_create_edges_from_isec_data + */ +static void lineart_init_isec_thread(LineartIsecData *d, LineartRenderBuffer *rb, int thread_count) { - /* Testing_triangle->testing[0] is used to store pairing triangle reference. - * See definition of LineartTriangleThread for more info. */ - LineartTriangle *testing_triangle; - LineartTriangleThread *tt; + d->threads = MEM_callocN(sizeof(LineartIsecThread) * thread_count, "LineartIsecThread arr"); + d->rb = rb; + d->thread_count = thread_count; - double *G0 = tri->v[0]->gloc, *G1 = tri->v[1]->gloc, *G2 = tri->v[2]->gloc; + rb->isect_scheduled_up_to = rb->triangle_buffer_pointers.first; + rb->isect_scheduled_up_to_index = 0; + + for (int i = 0; i < thread_count; i++) { + LineartIsecThread *it = &d->threads[i]; + it->array = MEM_mallocN(sizeof(LineartIsecSingle) * 100, "LineartIsecSingle arr"); + it->max = 100; + it->current = 0; + it->thread_id = i; + it->rb = rb; + } +} + +static void lineart_destroy_isec_thread(LineartIsecData *d) +{ + for (int i = 0; i < d->thread_count; i++) { + LineartIsecThread *it = &d->threads[i]; + MEM_freeN(it->array); + } + MEM_freeN(d->threads); +} - /* If this is not the smallest subdiv bounding area. */ - if (ba->child) { - lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[0]); - lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[1]); - lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[2]); - lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[3]); +static void lineart_triangle_intersect_in_bounding_area(LineartTriangle *tri, + LineartBoundingArea *ba, + LineartIsecThread *th, + int up_to) +{ + BLI_assert(th != NULL); + + if (!th) { return; } - /* If this _is_ the smallest subdiv bounding area, then do the intersections there. */ - for (int i = 0; i < ba->triangle_count; i++) { - testing_triangle = ba->linked_triangles[i]; - tt = (LineartTriangleThread *)testing_triangle; + double *G0 = tri->v[0]->gloc, *G1 = tri->v[1]->gloc, *G2 = tri->v[2]->gloc; + + /* If this _is_ the smallest subdivision bounding area, then do the intersections there. */ + for (int i = 0; i < up_to; i++) { + /* Testing_triangle->testing[0] is used to store pairing triangle reference. + * See definition of LineartTriangleThread for more info. */ + LineartTriangle *testing_triangle = ba->linked_triangles[i]; + LineartTriangleThread *tt = (LineartTriangleThread *)testing_triangle; - if (testing_triangle == tri || tt->testing_e[0] == (LineartEdge *)tri) { + if (testing_triangle == tri || tt->testing_e[th->thread_id] == (LineartEdge *)tri) { continue; } - tt->testing_e[0] = (LineartEdge *)tri; + tt->testing_e[th->thread_id] = (LineartEdge *)tri; if ((testing_triangle->flags & LRT_TRIANGLE_NO_INTERSECTION) || ((testing_triangle->flags & LRT_TRIANGLE_INTERSECTION_ONLY) && @@ -3285,7 +3279,11 @@ static void lineart_triangle_intersect_in_bounding_area(LineartRenderBuffer *rb, } /* If we do need to compute intersection, then finally do it. */ - lineart_triangle_intersect(rb, tri, testing_triangle); + + double iv1[3], iv2[3]; + if (lineart_triangle_intersect_math(tri, testing_triangle, iv1, iv2)) { + lineart_add_isec_thread(th, iv1, iv2, tri, testing_triangle); + } } } @@ -3332,6 +3330,8 @@ static void lineart_destroy_render_data(LineartRenderBuffer *rb) MEM_freeN(rb->pending_edges.array); } + lineart_free_bounding_area_memories(rb); + lineart_mem_destroy(&rb->render_data_pool); } @@ -3470,14 +3470,13 @@ static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene, BLI_spin_init(&rb->lock_cuts); BLI_spin_init(&rb->render_data_pool.lock_mem); + rb->thread_count = BKE_render_num_threads(&scene->r); + return rb; } -static int lineart_triangle_size_get(const Scene *scene, LineartRenderBuffer *rb) +static int lineart_triangle_size_get(LineartRenderBuffer *rb) { - if (rb->thread_count == 0) { - rb->thread_count = BKE_render_num_threads(&scene->r); - } return sizeof(LineartTriangle) + (sizeof(LineartEdge *) * (rb->thread_count)); } @@ -3491,6 +3490,14 @@ static void lineart_main_bounding_area_make_initial(LineartRenderBuffer *rb) int row, col; LineartBoundingArea *ba; + /* Always make sure the shortest side has at least LRT_BA_ROWS tiles. */ + if (rb->w > rb->h) { + sp_w = sp_h * rb->w / rb->h; + } + else { + sp_h = sp_w * rb->h / rb->w; + } + /* Because NDC (Normalized Device Coordinates) range is (-1,1), * so the span for each initial tile is double of that in the (0,1) range. */ double span_w = (double)1 / sp_w * 2.0; @@ -3508,7 +3515,7 @@ static void lineart_main_bounding_area_make_initial(LineartRenderBuffer *rb) /* Initialize tiles. */ for (row = 0; row < sp_h; row++) { for (col = 0; col < sp_w; col++) { - ba = &rb->initial_bounding_areas[row * LRT_BA_ROWS + col]; + ba = &rb->initial_bounding_areas[row * rb->tile_count_x + col]; /* Set the four direction limits. */ ba->l = span_w * col - 1.0; @@ -3522,34 +3529,12 @@ static void lineart_main_bounding_area_make_initial(LineartRenderBuffer *rb) /* Init linked_triangles array. */ ba->max_triangle_count = LRT_TILE_SPLITTING_TRIANGLE_LIMIT; ba->max_line_count = LRT_TILE_EDGE_COUNT_INITIAL; - ba->linked_triangles = lineart_mem_acquire( - &rb->render_data_pool, sizeof(LineartTriangle *) * ba->max_triangle_count); - ba->linked_lines = lineart_mem_acquire(&rb->render_data_pool, - sizeof(LineartEdge *) * ba->max_line_count); + ba->linked_triangles = MEM_callocN(sizeof(LineartTriangle *) * ba->max_triangle_count, + "ba_linked_triangles"); + ba->linked_lines = MEM_callocN(sizeof(LineartEdge *) * ba->max_line_count, + "ba_linked_lines"); - /* Link adjacent ones. */ - if (row) { - lineart_list_append_pointer_pool( - &ba->up, - &rb->render_data_pool, - &rb->initial_bounding_areas[(row - 1) * LRT_BA_ROWS + col]); - } - if (col) { - lineart_list_append_pointer_pool(&ba->lp, - &rb->render_data_pool, - &rb->initial_bounding_areas[row * LRT_BA_ROWS + col - 1]); - } - if (row != sp_h - 1) { - lineart_list_append_pointer_pool( - &ba->bp, - &rb->render_data_pool, - &rb->initial_bounding_areas[(row + 1) * LRT_BA_ROWS + col]); - } - if (col != sp_w - 1) { - lineart_list_append_pointer_pool(&ba->rp, - &rb->render_data_pool, - &rb->initial_bounding_areas[row * LRT_BA_ROWS + col + 1]); - } + BLI_spin_init(&ba->lock); } } } @@ -3697,17 +3682,68 @@ static void lineart_bounding_areas_connect_new(LineartRenderBuffer *rb, LineartB BLI_listbase_clear(&root->bp); } +static void lineart_bounding_areas_connect_recursive(LineartRenderBuffer *rb, + LineartBoundingArea *root) +{ + if (root->child) { + lineart_bounding_areas_connect_new(rb, root); + for (int i = 0; i < 4; i++) { + lineart_bounding_areas_connect_recursive(rb, &root->child[i]); + } + } +} + +static void lineart_main_bounding_areas_connect_post(LineartRenderBuffer *rb) +{ + int total_tile_initial = rb->tile_count_x * rb->tile_count_y; + int tiles_per_row = rb->tile_count_x; + + for (int row = 0; row < rb->tile_count_y; row++) { + for (int col = 0; col < rb->tile_count_x; col++) { + LineartBoundingArea *ba = &rb->initial_bounding_areas[row * tiles_per_row + col]; + /* Link adjacent ones. */ + if (row) { + lineart_list_append_pointer_pool( + &ba->up, + &rb->render_data_pool, + &rb->initial_bounding_areas[(row - 1) * tiles_per_row + col]); + } + if (col) { + lineart_list_append_pointer_pool( + &ba->lp, + &rb->render_data_pool, + &rb->initial_bounding_areas[row * tiles_per_row + col - 1]); + } + if (row != rb->tile_count_y - 1) { + lineart_list_append_pointer_pool( + &ba->bp, + &rb->render_data_pool, + &rb->initial_bounding_areas[(row + 1) * tiles_per_row + col]); + } + if (col != rb->tile_count_x - 1) { + lineart_list_append_pointer_pool( + &ba->rp, + &rb->render_data_pool, + &rb->initial_bounding_areas[row * tiles_per_row + col + 1]); + } + } + } + for (int i = 0; i < total_tile_initial; i++) { + lineart_bounding_areas_connect_recursive(rb, &rb->initial_bounding_areas[i]); + } +} + /** - * Subdivide a tile after one tile contains too many triangles. + * Subdivide a tile after one tile contains too many triangles, then re-link triangles into all the + * child tiles. */ static void lineart_bounding_area_split(LineartRenderBuffer *rb, LineartBoundingArea *root, int recursive_level) { - LineartBoundingArea *ba = lineart_mem_acquire(&rb->render_data_pool, - sizeof(LineartBoundingArea) * 4); - LineartTriangle *tri; + LineartBoundingArea *ba = lineart_mem_acquire_thread(&rb->render_data_pool, + sizeof(LineartBoundingArea) * 4); ba[0].l = root->cx; ba[0].r = root->r; ba[0].u = root->u; @@ -3736,42 +3772,46 @@ static void lineart_bounding_area_split(LineartRenderBuffer *rb, ba[3].cx = (ba[3].l + ba[3].r) / 2; ba[3].cy = (ba[3].u + ba[3].b) / 2; - root->child = ba; - - lineart_bounding_areas_connect_new(rb, root); - - /* Init linked_triangles array. */ + /* Init linked_triangles array and locks. */ for (int i = 0; i < 4; i++) { ba[i].max_triangle_count = LRT_TILE_SPLITTING_TRIANGLE_LIMIT; ba[i].max_line_count = LRT_TILE_EDGE_COUNT_INITIAL; - ba[i].linked_triangles = lineart_mem_acquire( - &rb->render_data_pool, sizeof(LineartTriangle *) * LRT_TILE_SPLITTING_TRIANGLE_LIMIT); - ba[i].linked_lines = lineart_mem_acquire(&rb->render_data_pool, - sizeof(LineartEdge *) * LRT_TILE_EDGE_COUNT_INITIAL); + ba[i].linked_triangles = MEM_callocN(sizeof(LineartTriangle *) * ba[i].max_triangle_count, + "ba_linked_triangles"); + ba[i].linked_lines = MEM_callocN(sizeof(LineartEdge *) * ba[i].max_line_count, + "ba_linked_lines"); + BLI_spin_init(&ba[i].lock); } for (int i = 0; i < root->triangle_count; i++) { - tri = root->linked_triangles[i]; - LineartBoundingArea *cba = root->child; + LineartTriangle *tri = root->linked_triangles[i]; + double b[4]; b[0] = MIN3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]); b[1] = MAX3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]); b[2] = MAX3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]); b[3] = MIN3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]); - if (LRT_BOUND_AREA_CROSSES(b, &cba[0].l)) { - lineart_bounding_area_link_triangle(rb, &cba[0], tri, b, 0, recursive_level + 1, false); + + /* Re-link triangles into child tiles, not doing intersection lines during this because this + * batch of triangles are all tested with each other for intersections. */ + if (LRT_BOUND_AREA_CROSSES(b, &ba[0].l)) { + lineart_bounding_area_link_triangle(rb, &ba[0], tri, b, 0, recursive_level + 1, false, NULL); } - if (LRT_BOUND_AREA_CROSSES(b, &cba[1].l)) { - lineart_bounding_area_link_triangle(rb, &cba[1], tri, b, 0, recursive_level + 1, false); + if (LRT_BOUND_AREA_CROSSES(b, &ba[1].l)) { + lineart_bounding_area_link_triangle(rb, &ba[1], tri, b, 0, recursive_level + 1, false, NULL); } - if (LRT_BOUND_AREA_CROSSES(b, &cba[2].l)) { - lineart_bounding_area_link_triangle(rb, &cba[2], tri, b, 0, recursive_level + 1, false); + if (LRT_BOUND_AREA_CROSSES(b, &ba[2].l)) { + lineart_bounding_area_link_triangle(rb, &ba[2], tri, b, 0, recursive_level + 1, false, NULL); } - if (LRT_BOUND_AREA_CROSSES(b, &cba[3].l)) { - lineart_bounding_area_link_triangle(rb, &cba[3], tri, b, 0, recursive_level + 1, false); + if (LRT_BOUND_AREA_CROSSES(b, &ba[3].l)) { + lineart_bounding_area_link_triangle(rb, &ba[3], tri, b, 0, recursive_level + 1, false, NULL); } } + /* At this point the child tiles are fully initialized and it's safe for new triangles to be + * inserted, so assign root->child for #lineart_bounding_area_link_triangle to use. */ + root->child = ba; + rb->bounding_area_count += 3; } @@ -3853,8 +3893,17 @@ static bool lineart_bounding_area_triangle_intersect(LineartRenderBuffer *fb, } /** - * 1) Link triangles with bounding areas for later occlusion test. - * 2) Test triangles with existing(added previously) triangles for intersection lines. + * This function does two things: + * + * 1) Builds a quad-tree under rb->InitialBoundingAreas to achieve good geometry separation for + * fast overlapping test between triangles and lines. This acceleration structure makes the + * occlusion stage much faster. + * + * 2) Test triangles with other triangles that are previously linked into each tile + * (#LineartBoundingArea) for intersection lines. When splitting the tile into 4 children and + * re-linking triangles into the child tiles, intersections are inhibited so we don't get + * duplicated intersection lines. + * */ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb, LineartBoundingArea *root_ba, @@ -3862,27 +3911,18 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb, double *LRUB, int recursive, int recursive_level, - bool do_intersection) + bool do_intersection, + struct LineartIsecThread *th) { if (!lineart_bounding_area_triangle_intersect(rb, tri, root_ba)) { return; } - if (root_ba->child == NULL) { - lineart_bounding_area_triangle_add(rb, root_ba, tri); - /* If splitting doesn't improve triangle separation, then shouldn't allow splitting anymore. - * Here we use recursive limit. This is especially useful in orthographic render, - * where a lot of faces could easily line up perfectly in image space, - * which can not be separated by simply slicing the image tile. */ - if (root_ba->triangle_count >= LRT_TILE_SPLITTING_TRIANGLE_LIMIT && recursive && - recursive_level < rb->tile_recursive_level) { - lineart_bounding_area_split(rb, root_ba, recursive_level); - } - if (recursive && do_intersection && rb->use_intersections) { - lineart_triangle_intersect_in_bounding_area(rb, tri, root_ba); - } - } - else { - LineartBoundingArea *ba = root_ba->child; + + LineartBoundingArea *old_ba = root_ba; + + if (old_ba->child) { + /* If old_ba->child is not NULL, then tile splitting is fully finished, safe to directly insert + * into child tiles. */ double *B1 = LRUB; double b[4]; if (!LRUB) { @@ -3892,21 +3932,83 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb, b[3] = MIN3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]); B1 = b; } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[0].l)) { - lineart_bounding_area_link_triangle( - rb, &ba[0], tri, B1, recursive, recursive_level + 1, do_intersection); + for (int iba = 0; iba < 4; iba++) { + if (LRT_BOUND_AREA_CROSSES(B1, &old_ba->child[iba].l)) { + lineart_bounding_area_link_triangle( + rb, &old_ba->child[iba], tri, B1, recursive, recursive_level + 1, do_intersection, th); + } + } + return; + } + + /* When splitting tiles, triangles are relinked into new tiles by a single thread, #th is NULL + * in that situation. */ + if (th) { + BLI_spin_lock(&old_ba->lock); + } + + /* If there are still space left in this tile for insertion. */ + if (old_ba->triangle_count < old_ba->max_triangle_count) { + const uint32_t old_tri_count = old_ba->triangle_count; + + old_ba->linked_triangles[old_ba->triangle_count++] = tri; + + /* Do intersections in place. */ + if (do_intersection && rb->use_intersections) { + lineart_triangle_intersect_in_bounding_area(tri, old_ba, th, old_tri_count); + } + + if (th) { + BLI_spin_unlock(&old_ba->lock); + } + } + else { /* We need to wait for either splitting or array extension to be done. */ + + if (recursive_level < rb->tile_recursive_level) { + if (!old_ba->child) { + /* old_ba->child==NULL, means we are the thread that's doing the splitting. */ + lineart_bounding_area_split(rb, old_ba, recursive_level); + } /* Otherwise other thread has completed the splitting process. */ + } + else { + if (old_ba->triangle_count == old_ba->max_triangle_count) { + /* Means we are the thread that's doing the extension. */ + lineart_bounding_area_triangle_reallocate(old_ba); + } /* Otherwise other thread has completed the extending the array. */ } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[1].l)) { - lineart_bounding_area_link_triangle( - rb, &ba[1], tri, B1, recursive, recursive_level + 1, do_intersection); + + /* Unlock before going into recursive call. */ + if (th) { + BLI_spin_unlock(&old_ba->lock); } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[2].l)) { - lineart_bounding_area_link_triangle( - rb, &ba[2], tri, B1, recursive, recursive_level + 1, do_intersection); + + /* Of course we still have our own triangle needs to be added. */ + lineart_bounding_area_link_triangle( + rb, root_ba, tri, LRUB, recursive, recursive_level, do_intersection, th); + } +} + +static void lineart_free_bounding_area_memory(LineartBoundingArea *ba, bool recursive) +{ + BLI_spin_end(&ba->lock); + if (ba->linked_lines) { + MEM_freeN(ba->linked_lines); + } + if (ba->linked_triangles) { + MEM_freeN(ba->linked_triangles); + } + if (recursive && ba->child) { + for (int i = 0; i < 4; i++) { + lineart_free_bounding_area_memory(&ba->child[i], recursive); } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[3].l)) { - lineart_bounding_area_link_triangle( - rb, &ba[3], tri, B1, recursive, recursive_level + 1, do_intersection); + } +} +static void lineart_free_bounding_area_memories(LineartRenderBuffer *rb) +{ + for (int i = 0; i < rb->tile_count_y; i++) { + for (int j = 0; j < rb->tile_count_x; j++) { + lineart_free_bounding_area_memory(&rb->initial_bounding_areas[i * rb->tile_count_x + j], + true); } } } @@ -3916,7 +4018,7 @@ static void lineart_bounding_area_link_edge(LineartRenderBuffer *rb, LineartEdge *e) { if (root_ba->child == NULL) { - lineart_bounding_area_line_add(rb, root_ba, e); + lineart_bounding_area_line_add(root_ba, e); } else { if (lineart_bounding_area_edge_intersect( @@ -3950,7 +4052,7 @@ static void lineart_main_link_lines(LineartRenderBuffer *rb) for (row = r1; row != r2 + 1; row++) { for (col = c1; col != c2 + 1; col++) { lineart_bounding_area_link_edge( - rb, &rb->initial_bounding_areas[row * LRT_BA_ROWS + col], e); + rb, &rb->initial_bounding_areas[row * rb->tile_count_x + col], e); } } } @@ -4078,7 +4180,7 @@ LineartBoundingArea *MOD_lineart_get_parent_bounding_area(LineartRenderBuffer *r row = 0; } - return &rb->initial_bounding_areas[row * LRT_BA_ROWS + col]; + return &rb->initial_bounding_areas[row * rb->tile_count_x + col]; } static LineartBoundingArea *lineart_get_bounding_area(LineartRenderBuffer *rb, double x, double y) @@ -4100,7 +4202,7 @@ static LineartBoundingArea *lineart_get_bounding_area(LineartRenderBuffer *rb, d c = rb->tile_count_x - 1; } - iba = &rb->initial_bounding_areas[r * LRT_BA_ROWS + c]; + iba = &rb->initial_bounding_areas[r * rb->tile_count_x + c]; while (iba->child) { if (x > iba->cx) { if (y > iba->cy) { @@ -4131,39 +4233,144 @@ LineartBoundingArea *MOD_lineart_get_bounding_area(LineartRenderBuffer *rb, doub return NULL; } +static void lineart_add_triangles_worker(TaskPool *__restrict UNUSED(pool), LineartIsecThread *th) +{ + LineartRenderBuffer *rb = th->rb; + int _dir_control = 0; + while (lineart_schedule_new_triangle_task(th)) { + for (LineartElementLinkNode *eln = th->pending_from; eln != th->pending_to->next; + eln = eln->next) { + int index_start = eln == th->pending_from ? th->index_from : 0; + int index_end = eln == th->pending_to ? th->index_to : eln->element_count; + LineartTriangle *tri = (void *)(((uchar *)eln->pointer) + rb->triangle_size * index_start); + for (int ei = index_start; ei < index_end; ei++) { + int x1, x2, y1, y2; + int r, co; + if ((tri->flags & LRT_CULL_USED) || (tri->flags & LRT_CULL_DISCARD)) { + tri = (void *)(((uchar *)tri) + rb->triangle_size); + continue; + } + if (lineart_get_triangle_bounding_areas(rb, tri, &y1, &y2, &x1, &x2)) { + _dir_control++; + for (co = x1; co <= x2; co++) { + for (r = y1; r <= y2; r++) { + lineart_bounding_area_link_triangle( + rb, + &rb->initial_bounding_areas[r * rb->tile_count_x + co], + tri, + 0, + 1, + 0, + (!(tri->flags & LRT_TRIANGLE_NO_INTERSECTION)), + th); + } + } + } /* Else throw away. */ + tri = (void *)(((uchar *)tri) + rb->triangle_size); + } + } + } +} + +static void lineart_create_edges_from_isec_data(LineartIsecData *d) +{ + LineartRenderBuffer *rb = d->rb; + double ZMax = rb->far_clip; + double ZMin = rb->near_clip; + + for (int i = 0; i < d->thread_count; i++) { + LineartIsecThread *th = &d->threads[i]; + if (G.debug_value == 4000) { + printf("Thread %d isec generated %d lines.\n", i, th->current); + } + if (!th->current) { + continue; + } + /* We don't care about removing duplicated vert in this method, chaining can handle that, + * and it saves us from using locks and look up tables. */ + LineartVertIntersection *v = lineart_mem_acquire( + &rb->render_data_pool, sizeof(LineartVertIntersection) * th->current * 2); + LineartEdge *e = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdge) * th->current); + LineartEdgeSegment *es = lineart_mem_acquire(&rb->render_data_pool, + sizeof(LineartEdgeSegment) * th->current); + for (int j = 0; j < th->current; j++) { + LineartVertIntersection *v1i = v; + LineartVertIntersection *v2i = v + 1; + LineartIsecSingle *is = &th->array[j]; + v1i->intersecting_with = is->tri1; + v2i->intersecting_with = is->tri2; + LineartVert *v1 = (LineartVert *)v1i; + LineartVert *v2 = (LineartVert *)v2i; + v1->flag |= LRT_VERT_HAS_INTERSECTION_DATA; + v2->flag |= LRT_VERT_HAS_INTERSECTION_DATA; + copy_v3db_v3fl(v1->gloc, is->v1); + copy_v3db_v3fl(v2->gloc, is->v2); + /* The intersection line has been generated only in geometry space, so we need to transform + * them as well. */ + mul_v4_m4v3_db(v1->fbcoord, rb->view_projection, v1->gloc); + mul_v4_m4v3_db(v2->fbcoord, rb->view_projection, v2->gloc); + mul_v3db_db(v1->fbcoord, (1 / v1->fbcoord[3])); + mul_v3db_db(v2->fbcoord, (1 / v2->fbcoord[3])); + + v1->fbcoord[0] -= rb->shift_x * 2; + v1->fbcoord[1] -= rb->shift_y * 2; + v2->fbcoord[0] -= rb->shift_x * 2; + v2->fbcoord[1] -= rb->shift_y * 2; + + /* This z transformation is not the same as the rest of the part, because the data don't go + * through normal perspective division calls in the pipeline, but this way the 3D result and + * occlusion on the generated line is correct, and we don't really use 2D for viewport stroke + * generation anyway. */ + v1->fbcoord[2] = ZMin * ZMax / (ZMax - fabs(v1->fbcoord[2]) * (ZMax - ZMin)); + v2->fbcoord[2] = ZMin * ZMax / (ZMax - fabs(v2->fbcoord[2]) * (ZMax - ZMin)); + e->v1 = v1; + e->v2 = v2; + e->t1 = is->tri1; + e->t2 = is->tri2; + e->flags = LRT_EDGE_FLAG_INTERSECTION; + e->intersection_mask = (is->tri1->intersection_mask | is->tri2->intersection_mask); + BLI_addtail(&e->segments, es); + + lineart_add_edge_to_array(&rb->pending_edges, e); + + v += 2; + e++; + es++; + } + } +} + /** - * Sequentially add triangles into render buffer. This also does intersection along the way. + * Sequentially add triangles into render buffer, intersection lines between those triangles will + * also be computed at the same time. */ static void lineart_main_add_triangles(LineartRenderBuffer *rb) { - LineartTriangle *tri; - int i, lim; - int x1, x2, y1, y2; - int r, co; + double t_start; + if (G.debug_value == 4000) { + t_start = PIL_check_seconds_timer(); + } - LISTBASE_FOREACH (LineartElementLinkNode *, eln, &rb->triangle_buffer_pointers) { - tri = eln->pointer; - lim = eln->element_count; - for (i = 0; i < lim; i++) { - if ((tri->flags & LRT_CULL_USED) || (tri->flags & LRT_CULL_DISCARD)) { - tri = (void *)(((uchar *)tri) + rb->triangle_size); - continue; - } - if (lineart_get_triangle_bounding_areas(rb, tri, &y1, &y2, &x1, &x2)) { - for (co = x1; co <= x2; co++) { - for (r = y1; r <= y2; r++) { - lineart_bounding_area_link_triangle(rb, - &rb->initial_bounding_areas[r * LRT_BA_ROWS + co], - tri, - 0, - 1, - 0, - (!(tri->flags & LRT_TRIANGLE_NO_INTERSECTION))); - } - } - } /* Else throw away. */ - tri = (void *)(((uchar *)tri) + rb->triangle_size); - } + /* Initialize per-thread data for thread task scheduling information and storing intersection + * results. */ + LineartIsecData d = {0}; + lineart_init_isec_thread(&d, rb, rb->thread_count); + + TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH); + for (int i = 0; i < rb->thread_count; i++) { + BLI_task_pool_push(tp, (TaskRunFunction)lineart_add_triangles_worker, &d.threads[i], 0, NULL); + } + BLI_task_pool_work_and_wait(tp); + BLI_task_pool_free(tp); + + /* Create actual lineart edges from intersection results. */ + lineart_create_edges_from_isec_data(&d); + + lineart_destroy_isec_thread(&d); + + if (G.debug_value == 4000) { + double t_elapsed = PIL_check_seconds_timer() - t_start; + printf("Line art intersection time: %f\n", t_elapsed); } } @@ -4466,7 +4673,7 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, /* Triangle thread testing data size varies depending on the thread count. * See definition of LineartTriangleThread for details. */ - rb->triangle_size = lineart_triangle_size_get(scene, rb); + rb->triangle_size = lineart_triangle_size_get(rb); /* FIXME(Yiming): See definition of int #LineartRenderBuffer::_source_type for detailed. */ rb->_source_type = lmd->source_type; @@ -4506,6 +4713,10 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, * can do its job. */ lineart_main_add_triangles(rb); + /* Re-link bounding areas because they have been subdivided by worker threads and we need + * adjacent info. */ + lineart_main_bounding_areas_connect_post(rb); + /* Link lines to acceleration structure, this can only be done after perspective division, if * we do it after triangles being added, the acceleration structure has already been * subdivided, this way we do less list manipulations. */ diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h index 1a197c8b4b7..2114ca1dc91 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h @@ -80,9 +80,9 @@ void lineart_count_and_print_render_buffer_memory(struct LineartRenderBuffer *rb #define LRT_BOUND_AREA_CROSSES(b1, b2) \ ((b1)[0] < (b2)[1] && (b1)[1] > (b2)[0] && (b1)[3] < (b2)[2] && (b1)[2] > (b2)[3]) -/* Initial bounding area row/column count, setting 4 is the simplest way algorithm could function - * efficiently. */ -#define LRT_BA_ROWS 4 +/* Initial bounding area row/column count, setting 10 is tested to be relatively optimal for the + * performance under current algorithm. */ +#define LRT_BA_ROWS 10 #ifdef __cplusplus extern "C" { diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index e78c86ae196..faf68cf2197 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -447,18 +447,18 @@ set(SRC_SHADER_CREATE_INFOS ../draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh ../draw/engines/gpencil/shaders/infos/gpencil_info.hh ../draw/engines/gpencil/shaders/infos/gpencil_vfx_info.hh - ../draw/engines/overlay/shaders/infos/antialiasing_info.hh - ../draw/engines/overlay/shaders/infos/armature_info.hh - ../draw/engines/overlay/shaders/infos/background_info.hh - ../draw/engines/overlay/shaders/infos/edit_mode_info.hh - ../draw/engines/overlay/shaders/infos/extra_info.hh - ../draw/engines/overlay/shaders/infos/facing_info.hh - ../draw/engines/overlay/shaders/infos/grid_info.hh - ../draw/engines/overlay/shaders/infos/outline_info.hh - ../draw/engines/overlay/shaders/infos/paint_info.hh - ../draw/engines/overlay/shaders/infos/sculpt_info.hh - ../draw/engines/overlay/shaders/infos/volume_info.hh - ../draw/engines/overlay/shaders/infos/wireframe_info.hh + ../draw/engines/overlay/shaders/infos/overlay_antialiasing_info.hh + ../draw/engines/overlay/shaders/infos/overlay_armature_info.hh + ../draw/engines/overlay/shaders/infos/overlay_background_info.hh + ../draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh + ../draw/engines/overlay/shaders/infos/overlay_extra_info.hh + ../draw/engines/overlay/shaders/infos/overlay_facing_info.hh + ../draw/engines/overlay/shaders/infos/overlay_grid_info.hh + ../draw/engines/overlay/shaders/infos/overlay_outline_info.hh + ../draw/engines/overlay/shaders/infos/overlay_paint_info.hh + ../draw/engines/overlay/shaders/infos/overlay_sculpt_info.hh + ../draw/engines/overlay/shaders/infos/overlay_volume_info.hh + ../draw/engines/overlay/shaders/infos/overlay_wireframe_info.hh ../draw/engines/select/shaders/infos/select_id_info.hh ../draw/engines/workbench/shaders/infos/workbench_composite_info.hh ../draw/engines/workbench/shaders/infos/workbench_effect_antialiasing_info.hh diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index 41565556f30..016db7e42c9 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -87,7 +87,7 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, const float *vmask, const void *vcol_data, int vcol_type, - AttributeDomain vcol_domain, + eAttrDomain vcol_domain, const int *sculpt_face_sets, int face_sets_color_seed, int face_sets_color_default, diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index fff90e6f8ff..c0633f0323d 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -7,7 +7,7 @@ #pragma once -#include "DNA_customdata_types.h" /* for CustomDataType */ +#include "DNA_customdata_types.h" /* for eCustomDataType */ #include "DNA_image_types.h" #include "DNA_listBase.h" @@ -130,9 +130,9 @@ typedef void (*GPUCodegenCallbackFn)(void *thunk, GPUMaterial *mat, GPUCodegenOu GPUNodeLink *GPU_constant(const float *num); GPUNodeLink *GPU_uniform(const float *num); -GPUNodeLink *GPU_attribute(GPUMaterial *mat, CustomDataType type, const char *name); +GPUNodeLink *GPU_attribute(GPUMaterial *mat, eCustomDataType type, const char *name); GPUNodeLink *GPU_attribute_with_default(GPUMaterial *mat, - CustomDataType type, + eCustomDataType type, const char *name, eGPUDefaultValue default_value); GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat, const char *name, bool use_dupli); @@ -259,7 +259,7 @@ void GPU_pass_cache_free(void); typedef struct GPUMaterialAttribute { struct GPUMaterialAttribute *next, *prev; - int type; /* CustomDataType */ + int type; /* eCustomDataType */ char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ char input_name[12 + 1]; /* GPU_MAX_SAFE_ATTR_NAME + 1 */ eGPUType gputype; diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index f1bb8b180bd..1ae7de50c18 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -202,7 +202,7 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, const float *vmask, const void *vcol_data, int vcol_type, - AttributeDomain vcol_domain, + eAttrDomain vcol_domain, const int *sculpt_face_sets, int face_sets_color_seed, int face_sets_color_default, diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c index 91fb0544cf6..cac6f7cb38b 100644 --- a/source/blender/gpu/intern/gpu_node_graph.c +++ b/source/blender/gpu/intern/gpu_node_graph.c @@ -328,7 +328,7 @@ void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph) /* Attributes and Textures */ -static char attr_prefix_get(CustomDataType type) +static char attr_prefix_get(eCustomDataType type) { switch (type) { case CD_TANGENT: @@ -364,7 +364,7 @@ static void attr_input_name(GPUMaterialAttribute *attr) /** Add a new varying attribute of given type and name. Returns NULL if out of slots. */ static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph, - CustomDataType type, + eCustomDataType type, const char *name) { /* Find existing attribute. */ @@ -468,7 +468,7 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph, /* Creating Inputs */ -GPUNodeLink *GPU_attribute(GPUMaterial *mat, const CustomDataType type, const char *name) +GPUNodeLink *GPU_attribute(GPUMaterial *mat, const eCustomDataType type, const char *name) { GPUNodeGraph *graph = gpu_material_node_graph(mat); GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, type, name); @@ -491,7 +491,7 @@ GPUNodeLink *GPU_attribute(GPUMaterial *mat, const CustomDataType type, const ch } GPUNodeLink *GPU_attribute_with_default(GPUMaterial *mat, - const CustomDataType type, + const eCustomDataType type, const char *name, eGPUDefaultValue default_value) { diff --git a/source/blender/gpu/metal/mtl_state.mm b/source/blender/gpu/metal/mtl_state.mm index 5f52bc55f72..fa2f5c54391 100644 --- a/source/blender/gpu/metal/mtl_state.mm +++ b/source/blender/gpu/metal/mtl_state.mm @@ -532,9 +532,11 @@ void MTLStateManager::set_blend(const eGPUBlend value) /* NOTE(Metal): Granular option for specifying before/after stages for a barrier * Would be a useful feature. */ -/*void MTLStateManager::issue_barrier(eGPUBarrier barrier_bits, +#if 0 +void MTLStateManager::issue_barrier(eGPUBarrier barrier_bits, eGPUStageBarrierBits before_stages, - eGPUStageBarrierBits after_stages) */ + eGPUStageBarrierBits after_stages) +#endif void MTLStateManager::issue_barrier(eGPUBarrier barrier_bits) { /* NOTE(Metal): The Metal API implicitly tracks dependencies between resources. diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl index 4c9ff31622f..fed7ac7df66 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl @@ -1,6 +1,6 @@ #pragma BLENDER_REQUIRE(gpu_shader_material_tangent.glsl) -void node_geometry(vec3 orco, +void node_geometry(vec3 orco_attr, out vec3 position, out vec3 normal, out vec3 tangent, @@ -21,8 +21,8 @@ void node_geometry(vec3 orco, tangent = g_data.curve_T; } else { - tangent_orco_z(orco, orco); - node_tangent(orco, tangent); + tangent_orco_z(orco_attr, orco_attr); + node_tangent(orco_attr, tangent); } parametric = vec3(g_data.barycentric_coords, 0.0); diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h index 512dc674fc7..2f0d2f9b449 100644 --- a/source/blender/imbuf/IMB_colormanagement.h +++ b/source/blender/imbuf/IMB_colormanagement.h @@ -181,7 +181,6 @@ void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer, int width, int height, const struct ImBuf *ibuf, - bool compress_as_srgb, bool store_premultiplied); void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer, int offset_x, @@ -519,10 +518,10 @@ enum { * \{ */ void IMB_colormanagement_blackbody_temperature_to_rgb_table(float *r_table, - const int width, - const float min, - const float max); -void IMB_colormanagement_wavelength_to_rgb_table(float *r_table, const int width); + int width, + float min, + float max); +void IMB_colormanagement_wavelength_to_rgb_table(float *r_table, int width); /** \} */ diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 16cf0e2125e..a2459023e8e 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -176,7 +176,7 @@ typedef struct ImBuf { * avoid problems and use int. - campbell */ int x, y; - /** Active amount of bits/bitplanes */ + /** Active amount of bits/bit-planes. */ unsigned char planes; /** Number of channels in `rect_float` (0 = 4 channel default) */ int channels; @@ -276,7 +276,7 @@ typedef struct ImBuf { } ImBuf; /** - * \brief userflags: Flags used internally by blender for imagebuffers + * \brief userflags: Flags used internally by blender for image-buffers. */ enum { diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h index 67d1aefeacb..6e505746643 100644 --- a/source/blender/imbuf/intern/IMB_filetype.h +++ b/source/blender/imbuf/intern/IMB_filetype.h @@ -42,8 +42,8 @@ typedef struct ImFileType { * dimensions of the full-size image in r_width & r_height. */ struct ImBuf *(*load_filepath_thumbnail)(const char *filepath, - const int flags, - const size_t max_thumb_size, + int flags, + size_t max_thumb_size, char colorspace[IM_MAX_SPACE], size_t *r_width, size_t *r_height); @@ -155,8 +155,8 @@ struct ImBuf *imb_load_jpeg(const unsigned char *buffer, int flags, char colorspace[IM_MAX_SPACE]); struct ImBuf *imb_thumbnail_jpeg(const char *filepath, - const int flags, - const size_t max_thumb_size, + int flags, + size_t max_thumb_size, char colorspace[IM_MAX_SPACE], size_t *r_width, size_t *r_height); diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c index 6448d6cd76a..1a99d2a34d9 100644 --- a/source/blender/imbuf/intern/cineon/cineon_dpx.c +++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c @@ -121,8 +121,8 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filepath, int use_cineon } if (ibuf->rect_float != NULL && bitspersample != 8) { - /* don't use the float buffer to save 8 bpp picture to prevent color banding - * (there's no dithering algorithm behind the logImageSetDataRGBA function) */ + /* Don't use the float buffer to save 8 BPP picture to prevent color banding + * (there's no dithering algorithm behind the #logImageSetDataRGBA function). */ fbuf = (float *)MEM_mallocN(sizeof(float[4]) * ibuf->x * ibuf->y, "fbuf in imb_save_dpx_cineon"); diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index d4c9e78a299..33873b5daa7 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -597,7 +597,7 @@ static void colormanage_free_config(void) while (colorspace) { ColorSpace *colorspace_next = colorspace->next; - /* free precomputer processors */ + /* Free precomputed processors. */ if (colorspace->to_scene_linear) { OCIO_cpuProcessorRelease((OCIO_ConstCPUProcessorRcPtr *)colorspace->to_scene_linear); } @@ -673,7 +673,7 @@ void colormanagement_init(void) #ifdef WIN32 { - /* quite a hack to support loading configuration from path with non-acii symbols */ + /* Quite a hack to support loading configuration from path with non-ACII symbols. */ char short_name[256]; BLI_get_short_name(short_name, configfile); @@ -2211,21 +2211,14 @@ void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer, const int width, const int height, const struct ImBuf *ibuf, - const bool compress_as_srgb, const bool store_premultiplied) { - /* Convert byte buffer for texture storage on the GPU. These have builtin - * support for converting sRGB to linear, which allows us to store textures - * without precision or performance loss at minimal memory usage. */ + /* Byte buffer storage, only for sRGB and data texture since other + * color space conversions can't be done on the GPU. */ BLI_assert(ibuf->rect && ibuf->rect_float == NULL); + BLI_assert(IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace) || + IMB_colormanagement_space_is_data(ibuf->rect_colorspace)); - OCIO_ConstCPUProcessorRcPtr *processor = NULL; - if (compress_as_srgb && ibuf->rect_colorspace && - !IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace)) { - processor = colorspace_to_scene_linear_cpu_processor(ibuf->rect_colorspace); - } - - /* TODO(brecht): make this multi-threaded, or at least process in batches. */ const unsigned char *in_buffer = (unsigned char *)ibuf->rect; const bool use_premultiply = IMB_alpha_affects_rgb(ibuf) && store_premultiplied; @@ -2235,20 +2228,7 @@ void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer, const unsigned char *in = in_buffer + in_offset * 4; unsigned char *out = out_buffer + out_offset * 4; - if (processor != NULL) { - /* Convert to scene linear, to sRGB and premultiply. */ - for (int x = 0; x < width; x++, in += 4, out += 4) { - float pixel[4]; - rgba_uchar_to_float(pixel, in); - OCIO_cpuProcessorApplyRGB(processor, pixel); - linearrgb_to_srgb_v3_v3(pixel, pixel); - if (use_premultiply) { - mul_v3_fl(pixel, pixel[3]); - } - rgba_float_to_uchar(out, pixel); - } - } - else if (use_premultiply) { + if (use_premultiply) { /* Premultiply only. */ for (int x = 0; x < width; x++, in += 4, out += 4) { out[0] = (in[0] * in[3]) >> 8; @@ -2279,43 +2259,80 @@ void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer, { /* Float texture are stored in scene linear color space, with premultiplied * alpha depending on the image alpha mode. */ - const float *in_buffer = ibuf->rect_float; - const int in_channels = ibuf->channels; - const bool use_unpremultiply = IMB_alpha_affects_rgb(ibuf) && !store_premultiplied; - - for (int y = 0; y < height; y++) { - const size_t in_offset = (offset_y + y) * ibuf->x + offset_x; - const size_t out_offset = y * width; - const float *in = in_buffer + in_offset * in_channels; - float *out = out_buffer + out_offset * 4; - - if (in_channels == 1) { - /* Copy single channel. */ - for (int x = 0; x < width; x++, in += 1, out += 4) { - out[0] = in[0]; - out[1] = in[0]; - out[2] = in[0]; - out[3] = in[0]; + if (ibuf->rect_float) { + /* Float source buffer. */ + const float *in_buffer = ibuf->rect_float; + const int in_channels = ibuf->channels; + const bool use_unpremultiply = IMB_alpha_affects_rgb(ibuf) && !store_premultiplied; + + for (int y = 0; y < height; y++) { + const size_t in_offset = (offset_y + y) * ibuf->x + offset_x; + const size_t out_offset = y * width; + const float *in = in_buffer + in_offset * in_channels; + float *out = out_buffer + out_offset * 4; + + if (in_channels == 1) { + /* Copy single channel. */ + for (int x = 0; x < width; x++, in += 1, out += 4) { + out[0] = in[0]; + out[1] = in[0]; + out[2] = in[0]; + out[3] = in[0]; + } } - } - else if (in_channels == 3) { - /* Copy RGB. */ - for (int x = 0; x < width; x++, in += 3, out += 4) { - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = 1.0f; + else if (in_channels == 3) { + /* Copy RGB. */ + for (int x = 0; x < width; x++, in += 3, out += 4) { + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = 1.0f; + } } - } - else if (in_channels == 4) { - /* Copy or convert RGBA. */ - if (use_unpremultiply) { - for (int x = 0; x < width; x++, in += 4, out += 4) { - premul_to_straight_v4_v4(out, in); + else if (in_channels == 4) { + /* Copy or convert RGBA. */ + if (use_unpremultiply) { + for (int x = 0; x < width; x++, in += 4, out += 4) { + premul_to_straight_v4_v4(out, in); + } + } + else { + memcpy(out, in, sizeof(float[4]) * width); } } - else { - memcpy(out, in, sizeof(float[4]) * width); + } + } + else { + /* Byte source buffer. */ + const unsigned char *in_buffer = (unsigned char *)ibuf->rect; + const bool use_premultiply = IMB_alpha_affects_rgb(ibuf) && store_premultiplied; + + /* TODO(brecht): make this multi-threaded, or at least process in batches. */ + OCIO_ConstCPUProcessorRcPtr *processor = (ibuf->rect_colorspace) ? + colorspace_to_scene_linear_cpu_processor( + ibuf->rect_colorspace) : + NULL; + + for (int y = 0; y < height; y++) { + const size_t in_offset = (offset_y + y) * ibuf->x + offset_x; + const size_t out_offset = y * width; + const unsigned char *in = in_buffer + in_offset * 4; + float *out = out_buffer + out_offset * 4; + + /* Convert to scene linear, to sRGB and premultiply. */ + for (int x = 0; x < width; x++, in += 4, out += 4) { + float pixel[4]; + rgba_uchar_to_float(pixel, in); + if (processor) { + OCIO_cpuProcessorApplyRGB(processor, pixel); + } + else { + srgb_to_linearrgb_v3_v3(pixel, pixel); + } + if (use_premultiply) { + mul_v3_fl(pixel, pixel[3]); + } + copy_v4_v4(out, pixel); } } } diff --git a/source/blender/imbuf/intern/openexr/openexr_api.h b/source/blender/imbuf/intern/openexr/openexr_api.h index a62c87428b6..40a724c9f42 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.h +++ b/source/blender/imbuf/intern/openexr/openexr_api.h @@ -27,8 +27,8 @@ bool imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags); struct ImBuf *imb_load_openexr(const unsigned char *mem, size_t size, int flags, char *colorspace); struct ImBuf *imb_load_filepath_thumbnail_openexr(const char *filepath, - const int flags, - const size_t max_thumb_size, + int flags, + size_t max_thumb_size, char colorspace[], size_t *r_width, size_t *r_height); diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c index 8e004938a89..5feb0ceb515 100644 --- a/source/blender/imbuf/intern/util_gpu.c +++ b/source/blender/imbuf/intern/util_gpu.c @@ -28,17 +28,30 @@ static void imb_gpu_get_format(const ImBuf *ibuf, eGPUTextureFormat *r_texture_format) { const bool float_rect = (ibuf->rect_float != NULL); - const bool use_srgb = (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace) && - !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace)); - high_bitdepth = (!(ibuf->flags & IB_halffloat) && high_bitdepth); - - *r_data_format = (float_rect) ? GPU_DATA_FLOAT : GPU_DATA_UBYTE; if (float_rect) { - *r_texture_format = high_bitdepth ? GPU_RGBA32F : GPU_RGBA16F; + /* Float. */ + const bool use_high_bitdepth = (!(ibuf->flags & IB_halffloat) && high_bitdepth); + *r_data_format = GPU_DATA_FLOAT; + *r_texture_format = use_high_bitdepth ? GPU_RGBA32F : GPU_RGBA16F; } else { - *r_texture_format = use_srgb ? GPU_SRGB8_A8 : GPU_RGBA8; + if (IMB_colormanagement_space_is_data(ibuf->rect_colorspace) || + IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace)) { + /* Non-color data or scene linear, just store buffer as is. */ + *r_data_format = GPU_DATA_UBYTE; + *r_texture_format = GPU_RGBA8; + } + else if (IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace)) { + /* sRGB, store as byte texture that the GPU can decode directly. */ + *r_data_format = GPU_DATA_UBYTE; + *r_texture_format = GPU_SRGB8_A8; + } + else { + /* Other colorspace, store as half float texture to avoid precision loss. */ + *r_data_format = GPU_DATA_FLOAT; + *r_texture_format = GPU_RGBA16F; + } } } @@ -74,7 +87,6 @@ static bool IMB_gpu_get_compressed_format(const ImBuf *ibuf, eGPUTextureFormat * static void *imb_gpu_get_data(const ImBuf *ibuf, const bool do_rescale, const int rescale_size[2], - const bool compress_as_srgb, const bool store_premultiplied, bool *r_freedata) { @@ -99,14 +111,16 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, } } else { - /* Byte image is in original colorspace from the file. If the file is sRGB - * scene linear, or non-color data no conversion is needed. Otherwise we - * compress as scene linear + sRGB transfer function to avoid precision loss - * in common cases. + /* Byte image is in original colorspace from the file, and may need conversion. * * We must also convert to premultiplied for correct texture interpolation * and consistency with float images. */ - if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { + if (IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { + /* Non-color data, just store buffer as is. */ + } + else if (IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace) || + IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace)) { + /* sRGB or scene linear, store as byte texture that the GPU can decode directly. */ data_rect = MEM_mallocN(sizeof(uchar[4]) * ibuf->x * ibuf->y, __func__); *r_freedata = freedata = true; @@ -120,7 +134,24 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, * zero alpha areas, and appears generally closer to what game engines that we * want to be compatible with do. */ IMB_colormanagement_imbuf_to_byte_texture( - (uchar *)data_rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied); + (uchar *)data_rect, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied); + } + else { + /* Other colorspace, store as float texture to avoid precision loss. */ + data_rect = MEM_mallocN(sizeof(float[4]) * ibuf->x * ibuf->y, __func__); + *r_freedata = freedata = true; + + if (data_rect == NULL) { + return NULL; + } + + /* Texture storage of images is defined by the alpha mode of the image. The + * downside of this is that there can be artifacts near alpha edges. However, + * this allows us to use sRGB texture formats and preserves color values in + * zero alpha areas, and appears generally closer to what game engines that we + * want to be compatible with do. */ + IMB_colormanagement_imbuf_to_float_texture( + (float *)data_rect, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied); } } @@ -181,10 +212,9 @@ void IMB_update_gpu_texture_sub(GPUTexture *tex, eGPUTextureFormat tex_format; imb_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format); - const bool compress_as_srgb = (tex_format == GPU_SRGB8_A8); bool freebuf = false; - void *data = imb_gpu_get_data(ibuf, do_rescale, size, compress_as_srgb, use_premult, &freebuf); + void *data = imb_gpu_get_data(ibuf, do_rescale, size, use_premult, &freebuf); /* Update Texture. */ GPU_texture_update_sub(tex, data_format, data, x, y, z, w, h, 1); @@ -238,7 +268,6 @@ GPUTexture *IMB_create_gpu_texture(const char *name, eGPUTextureFormat tex_format; imb_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format); - const bool compress_as_srgb = (tex_format == GPU_SRGB8_A8); bool freebuf = false; /* Create Texture. */ @@ -250,7 +279,7 @@ GPUTexture *IMB_create_gpu_texture(const char *name, do_rescale = true; } BLI_assert(tex != NULL); - void *data = imb_gpu_get_data(ibuf, do_rescale, size, compress_as_srgb, use_premult, &freebuf); + void *data = imb_gpu_get_data(ibuf, do_rescale, size, use_premult, &freebuf); GPU_texture_update(tex, data_format, data); GPU_texture_anisotropic_filter(tex, true); diff --git a/source/blender/io/alembic/intern/abc_customdata.cc b/source/blender/io/alembic/intern/abc_customdata.cc index 633611cf1a6..6e4ec6d23fa 100644 --- a/source/blender/io/alembic/intern/abc_customdata.cc +++ b/source/blender/io/alembic/intern/abc_customdata.cc @@ -273,7 +273,7 @@ void write_custom_data(const OCompoundProperty &prop, CustomData *data, int data_type) { - CustomDataType cd_data_type = static_cast<CustomDataType>(data_type); + eCustomDataType cd_data_type = static_cast<eCustomDataType>(data_type); if (!CustomData_has_layer(data, cd_data_type)) { return; diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index 219bba285a7..d8c48357fc0 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -376,7 +376,7 @@ BLI_INLINE void read_uvs_params(CDStreamConfig &config, static void *add_customdata_cb(Mesh *mesh, const char *name, int data_type) { - CustomDataType cd_data_type = static_cast<CustomDataType>(data_type); + eCustomDataType cd_data_type = static_cast<eCustomDataType>(data_type); /* unsupported custom data type -- don't do anything. */ if (!ELEM(cd_data_type, CD_MLOOPUV, CD_PROP_BYTE_COLOR)) { diff --git a/source/blender/io/avi/AVI_avi.h b/source/blender/io/avi/AVI_avi.h index e3af171355d..0857b9191b2 100644 --- a/source/blender/io/avi/AVI_avi.h +++ b/source/blender/io/avi/AVI_avi.h @@ -235,7 +235,8 @@ AviError AVI_close_compress(AviMovie *movie); */ AviError AVI_set_compress_option( AviMovie *movie, int option_type, int stream, AviOption option, void *opt_data); -/* Hmmm... there should be some explanation about what these mean */ + +/* TODO: there should be some explanation about what these mean. */ /** * Compression option, for use in avi_set_compress_option */ diff --git a/source/blender/io/collada/BCAnimationSampler.cpp b/source/blender/io/collada/BCAnimationSampler.cpp index 29c17b500f3..cbb30ccf51d 100644 --- a/source/blender/io/collada/BCAnimationSampler.cpp +++ b/source/blender/io/collada/BCAnimationSampler.cpp @@ -225,24 +225,26 @@ bool BCAnimationSampler::is_animated_by_constraint(Object *ob, for (con = (bConstraint *)conlist->first; con; con = con->next) { ListBase targets = {nullptr, nullptr}; - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - if (!bc_validateConstraints(con)) { continue; } - if (cti && cti->get_constraint_targets) { + if (BKE_constraint_targets_get(con, &targets)) { bConstraintTarget *ct; Object *obtar; - cti->get_constraint_targets(con, &targets); + bool found = false; + for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) { obtar = ct->tar; if (obtar) { if (animated_objects.find(obtar) != animated_objects.end()) { - return true; + found = true; + break; } } } + BKE_constraint_targets_flush(con, &targets, true); + return found; } } return false; diff --git a/source/blender/io/collada/SceneExporter.cpp b/source/blender/io/collada/SceneExporter.cpp index ea95729666a..1b1da110573 100644 --- a/source/blender/io/collada/SceneExporter.cpp +++ b/source/blender/io/collada/SceneExporter.cpp @@ -191,24 +191,19 @@ void SceneExporter::writeNode(Object *ob) /* not ideal: add the target object name as another parameter. * No real mapping in the `.dae`. * Need support for multiple target objects also. */ - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - ListBase targets = {nullptr, nullptr}; - if (cti && cti->get_constraint_targets) { + ListBase targets = {nullptr, nullptr}; + if (BKE_constraint_targets_get(con, &targets)) { bConstraintTarget *ct; Object *obtar; - cti->get_constraint_targets(con, &targets); - for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) { obtar = ct->tar; std::string tar_id((obtar) ? id_name(obtar) : ""); colladaNode.addExtraTechniqueChildParameter("blender", con_tag, "target_id", tar_id); } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, true); - } + BKE_constraint_targets_flush(con, &targets, true); } con = con->next; diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index e2562eca69b..2c86bfff4da 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -143,7 +143,7 @@ static void assign_materials(Main *bmain, static void *add_customdata_cb(Mesh *mesh, const char *name, const int data_type) { - CustomDataType cd_data_type = static_cast<CustomDataType>(data_type); + eCustomDataType cd_data_type = static_cast<eCustomDataType>(data_type); void *cd_ptr; CustomData *loopdata; int numloops; diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 1989118bef9..451c921c4ef 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -472,7 +472,7 @@ typedef struct Library { ushort tag; char _pad_0[6]; - /* Temp data needed by read/write code, and liboverride recursive resync. */ + /** Temp data needed by read/write code, and lib-override recursive re-synchronized. */ int temp_index; /** See BLENDER_FILE_VERSION, BLENDER_FILE_SUBVERSION, needed for do_versions. */ short versionfile, subversionfile; diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index c1dfab8a041..e2b58cefef6 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -771,7 +771,7 @@ typedef enum eNlaStrip_Blend_Mode { NLASTRIP_MODE_COMBINE, } eNlaStrip_Blend_Mode; -/** NLA Strip Extrpolation Mode. */ +/** NLA Strip Extrapolation Mode. */ typedef enum eNlaStrip_Extrapolate_Mode { /* extend before first frame if no previous strips in track, * and always hold+extend last frame */ diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h index f409d1c0442..f2cd49b6dea 100644 --- a/source/blender/makesdna/DNA_brush_enums.h +++ b/source/blender/makesdna/DNA_brush_enums.h @@ -468,6 +468,7 @@ typedef enum eBrushCurvesSculptTool { CURVES_SCULPT_TOOL_SNAKE_HOOK = 2, CURVES_SCULPT_TOOL_ADD = 3, CURVES_SCULPT_TOOL_GROW_SHRINK = 4, + CURVES_SCULPT_TOOL_SELECTION_PAINT = 5, } eBrushCurvesSculptTool; /** When #BRUSH_ACCUMULATE is used */ diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 24e77ecf87f..d13496b21f7 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -97,7 +97,7 @@ typedef struct BrushGpencilSettings { /** Simplify adaptive factor */ float simplify_f; - /** Mix colorfactor */ + /** Mix color-factor. */ float vertex_factor; int vertex_mode; diff --git a/source/blender/makesdna/DNA_curves_types.h b/source/blender/makesdna/DNA_curves_types.h index 2388f04cc39..ed909c283c4 100644 --- a/source/blender/makesdna/DNA_curves_types.h +++ b/source/blender/makesdna/DNA_curves_types.h @@ -141,7 +141,12 @@ typedef struct Curves { * symmetrical geometry. */ char symmetry; - char _pad2[5]; + /** + * #eAttrDomain. The active selection mode domain. At most one selection mode can be active + * at a time. + */ + char selection_domain; + char _pad[4]; /** * Used as base mesh when curves represent e.g. hair or fur. This surface is used in edit modes. @@ -152,6 +157,13 @@ typedef struct Curves { */ struct Object *surface; + /** + * The name of the attribute on the surface #Mesh used to give meaning to the UV attachment + * coordinates stored on each curve. Expected to be a 2D vector attribute on the face corner + * domain. + */ + char *surface_uv_map; + /* Draw Cache. */ void *batch_cache; } Curves; @@ -159,6 +171,7 @@ typedef struct Curves { /** #Curves.flag */ enum { HA_DS_EXPAND = (1 << 0), + CV_SCULPT_SELECTION_ENABLED = (1 << 1), }; /** #Curves.symmetry */ diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index fe06e97946c..bc29de66cf9 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -81,7 +81,7 @@ typedef struct CustomData { } CustomData; /** #CustomData.type */ -typedef enum CustomDataType { +typedef enum eCustomDataType { /* Used by GLSL attributes in the cases when we need a delayed CD type * assignment (in the cases when we don't know in advance which layer * we are addressing). @@ -161,9 +161,9 @@ typedef enum CustomDataType { CD_HAIRLENGTH = 51, CD_NUMTYPES = 52, -} CustomDataType; +} eCustomDataType; -/* Bits for CustomDataMask */ +/* Bits for eCustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) // #define CD_MASK_MSTICKY (1 << CD_MSTICKY) /* DEPRECATED */ #define CD_MASK_MDEFORMVERT (1 << CD_MDEFORMVERT) diff --git a/source/blender/makesdna/DNA_lineart_types.h b/source/blender/makesdna/DNA_lineart_types.h index 5b3a23000d7..df496269644 100644 --- a/source/blender/makesdna/DNA_lineart_types.h +++ b/source/blender/makesdna/DNA_lineart_types.h @@ -48,8 +48,8 @@ typedef enum eLineartEdgeFlag { LRT_EDGE_FLAG_INTERSECTION = (1 << 4), LRT_EDGE_FLAG_LOOSE = (1 << 5), /* LRT_EDGE_FLAG_FOR_FUTURE = (1 << 7), */ - /* Limited to 8 bits for edge type flag, don't add anymore because BMEdge->head.eflag only has 8 - bits. So unless we changed this into a non-single-bit flag thing, we keep it this way. */ + /* Limited to 8 bits for edge type flag, don't add anymore because `BMEdge->head.eflag` only has + * 8 bits. So unless we changed this into a non-single-bit flag thing, we keep it this way. */ /** Also used as discarded line mark. */ LRT_EDGE_FLAG_CHAIN_PICKED = (1 << 8), LRT_EDGE_FLAG_CLIPPED = (1 << 9), diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index a0738883bf3..9dc2971b322 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -140,7 +140,7 @@ typedef struct bNodeSocket { short stack_type DNA_DEPRECATED; char display_shape; - /* #AttributeDomain used when the geometry nodes modifier creates an attribute for a group + /* #eAttrDomain used when the geometry nodes modifier creates an attribute for a group * output. */ char attribute_domain; /* Runtime-only cache of the number of input links, for multi-input sockets. */ @@ -1175,7 +1175,7 @@ typedef struct NodeDenoise { } NodeDenoise; typedef struct NodeMapRange { - /* CustomDataType */ + /* eCustomDataType */ uint8_t data_type; /* NodeMapRangeType. */ @@ -1185,14 +1185,14 @@ typedef struct NodeMapRange { } NodeMapRange; typedef struct NodeRandomValue { - /* CustomDataType. */ + /* eCustomDataType. */ uint8_t data_type; } NodeRandomValue; typedef struct NodeAccumulateField { - /* CustomDataType. */ + /* eCustomDataType. */ uint8_t data_type; - /* AttributeDomain. */ + /* eAttrDomain. */ uint8_t domain; } NodeAccumulateField; @@ -1362,9 +1362,9 @@ typedef struct NodeGeometryCurveSample { } NodeGeometryCurveSample; typedef struct NodeGeometryTransferAttribute { - /* CustomDataType. */ + /* eCustomDataType. */ int8_t data_type; - /* AttributeDomain. */ + /* eAttrDomain. */ int8_t domain; /* GeometryNodeAttributeTransferMode. */ uint8_t mode; @@ -1375,7 +1375,7 @@ typedef struct NodeGeometryRaycast { /* GeometryNodeRaycastMapMode. */ uint8_t mapping; - /* CustomDataType. */ + /* eCustomDataType. */ int8_t data_type; /* Deprecated input types in new Ray-cast node. Can be removed when legacy nodes are no longer @@ -1394,21 +1394,21 @@ typedef struct NodeGeometryMeshToPoints { } NodeGeometryMeshToPoints; typedef struct NodeGeometryAttributeCapture { - /* CustomDataType. */ + /* eCustomDataType. */ int8_t data_type; - /* AttributeDomain. */ + /* eAttrDomain. */ int8_t domain; } NodeGeometryAttributeCapture; typedef struct NodeGeometryStoreNamedAttribute { - /* CustomDataType. */ + /* eCustomDataType. */ int8_t data_type; - /* AttributeDomain. */ + /* eAttrDomain. */ int8_t domain; } NodeGeometryStoreNamedAttribute; typedef struct NodeGeometryInputNamedAttribute { - /* CustomDataType. */ + /* eCustomDataType. */ int8_t data_type; } NodeGeometryInputNamedAttribute; @@ -1424,19 +1424,19 @@ typedef struct NodeGeometryStringToCurves { } NodeGeometryStringToCurves; typedef struct NodeGeometryDeleteGeometry { - /* AttributeDomain. */ + /* eAttrDomain. */ int8_t domain; /* GeometryNodeDeleteGeometryMode. */ int8_t mode; } NodeGeometryDeleteGeometry; typedef struct NodeGeometryDuplicateElements { - /* AttributeDomain. */ + /* eAttrDomain. */ int8_t domain; } NodeGeometryDuplicateElements; typedef struct NodeGeometrySeparateGeometry { - /* AttributeDomain. */ + /* eAttrDomain. */ int8_t domain; } NodeGeometrySeparateGeometry; @@ -1446,7 +1446,7 @@ typedef struct NodeGeometryImageTexture { } NodeGeometryImageTexture; typedef struct NodeGeometryViewer { - /* CustomDataType. */ + /* eCustomDataType. */ int8_t data_type; } NodeGeometryViewer; diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index a54fd838bbe..db24a775edb 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -161,11 +161,11 @@ typedef struct Sequence { * Frames that use the first frame before data begins, * frames that use the last frame after data ends. */ - int startstill DNA_DEPRECATED, endstill DNA_DEPRECATED; + int startstill, endstill; /** Machine: the strip channel */ int machine; int _pad3; - /** Starting and ending points of the strip in the sequence. */ + /** Starting and ending points of the effect strip. Undefined for other strip types. */ int startdisp, enddisp; float sat; float mul; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 85649a31ea4..be073ef2c15 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1936,7 +1936,7 @@ typedef struct SpaceSpreadsheet { /* #GeometryComponentType. */ uint8_t geometry_component_type; - /* #AttributeDomain. */ + /* #eAttrDomain. */ uint8_t attribute_domain; /* eSpaceSpreadsheet_ObjectContext. */ uint8_t object_eval_state; @@ -2014,6 +2014,7 @@ typedef enum eSpreadsheetColumnValueType { SPREADSHEET_VALUE_TYPE_INSTANCES = 6, SPREADSHEET_VALUE_TYPE_STRING = 7, SPREADSHEET_VALUE_TYPE_BYTE_COLOR = 8, + SPREADSHEET_VALUE_TYPE_INT8 = 9, } eSpreadsheetColumnValueType; /** diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 275a89ec680..e449605ed81 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -314,7 +314,7 @@ typedef struct ThemeSpace { char _pad5[3]; float dash_alpha; - /* syntax for textwindow and nodes */ + /* Syntax for text-window and nodes. */ unsigned char syntaxl[4], syntaxs[4]; /* in nodespace used for backdrop matte */ unsigned char syntaxb[4], syntaxn[4]; /* in nodespace used for color input */ unsigned char syntaxv[4], syntaxc[4]; /* in nodespace used for converter group */ @@ -858,7 +858,7 @@ typedef struct UserDef { float glalphaclip; - /** #eAutokey_Mode, autokeying mode. */ + /** #eAutokey_Mode, auto-keying mode. */ short autokey_mode; /** Flags for autokeying. */ short autokey_flag; diff --git a/source/blender/makesrna/RNA_enum_items.h b/source/blender/makesrna/RNA_enum_items.h index 8c42bbe2ee6..fd264932363 100644 --- a/source/blender/makesrna/RNA_enum_items.h +++ b/source/blender/makesrna/RNA_enum_items.h @@ -147,6 +147,7 @@ DEF_ENUM(rna_enum_keymap_propvalue_items) DEF_ENUM(rna_enum_operator_context_items) DEF_ENUM(rna_enum_wm_report_items) +DEF_ENUM(rna_enum_wm_job_type_items) DEF_ENUM(rna_enum_property_type_items) DEF_ENUM(rna_enum_property_subtype_items) @@ -209,6 +210,7 @@ DEF_ENUM(rna_enum_attribute_type_items) DEF_ENUM(rna_enum_color_attribute_type_items) DEF_ENUM(rna_enum_attribute_type_with_auto_items) DEF_ENUM(rna_enum_attribute_domain_items) +DEF_ENUM(rna_enum_attribute_curves_domain_items) DEF_ENUM(rna_enum_color_attribute_domain_items) DEF_ENUM(rna_enum_attribute_domain_without_corner_items) DEF_ENUM(rna_enum_attribute_domain_with_auto_items) diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c index 0cea693cd2a..5af714660ed 100644 --- a/source/blender/makesrna/intern/rna_attribute.c +++ b/source/blender/makesrna/intern/rna_attribute.c @@ -106,6 +106,11 @@ const EnumPropertyItem rna_enum_color_attribute_domain_items[] = { {ATTR_DOMAIN_CORNER, "CORNER", 0, "Face Corner", ""}, {0, NULL, 0, NULL, NULL}}; +const EnumPropertyItem rna_enum_attribute_curves_domain_items[] = { + {ATTR_DOMAIN_POINT, "POINT", 0, "Control Point", ""}, + {ATTR_DOMAIN_CURVE, "CURVE", 0, "Curve", ""}, + {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME # include "BLI_math.h" @@ -124,7 +129,7 @@ static char *rna_Attribute_path(const PointerRNA *ptr) return BLI_sprintfN("attributes['%s']", layer->name); } -static StructRNA *srna_by_custom_data_layer_type(const CustomDataType type) +static StructRNA *srna_by_custom_data_layer_type(const eCustomDataType type) { switch (type) { case CD_PROP_FLOAT: @@ -373,7 +378,7 @@ static int rna_Attributes_noncolor_layer_skip(CollectionPropertyIterator *iter, /* Check valid domain here, too, keep in line with rna_AttributeGroup_color_length(). */ ID *id = iter->parent.owner_id; - AttributeDomain domain = BKE_id_attribute_domain(id, layer); + eAttrDomain domain = BKE_id_attribute_domain(id, layer); if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) { return 1; } diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 2735a00ee75..46b009191ca 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -249,6 +249,7 @@ const EnumPropertyItem rna_enum_brush_curves_sculpt_tool_items[] = { {CURVES_SCULPT_TOOL_SNAKE_HOOK, "SNAKE_HOOK", ICON_NONE, "Curves Snake Hook", ""}, {CURVES_SCULPT_TOOL_ADD, "ADD", ICON_NONE, "Add Curves", ""}, {CURVES_SCULPT_TOOL_GROW_SHRINK, "GROW_SHRINK", ICON_NONE, "Grow / Shrink Curves", ""}, + {CURVES_SCULPT_TOOL_SELECTION_PAINT, "SELECTION_PAINT", ICON_NONE, "Paint Selection", ""}, {0, NULL, 0, NULL, NULL}, }; @@ -885,6 +886,7 @@ static const EnumPropertyItem *rna_Brush_direction_itemf(bContext *C, case PAINT_MODE_SCULPT_CURVES: switch (me->curves_sculpt_tool) { case CURVES_SCULPT_TOOL_GROW_SHRINK: + case CURVES_SCULPT_TOOL_SELECTION_PAINT: return prop_direction_items; default: return DummyRNA_DEFAULT_items; diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 24f226eb6e6..1420ef36493 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -598,22 +598,17 @@ static const EnumPropertyItem *rna_Constraint_target_space_itemf(bContext *UNUSE bool *UNUSED(r_free)) { bConstraint *con = (bConstraint *)ptr->data; - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); - + if (BKE_constraint_targets_get(con, &targets)) { for (ct = targets.first; ct; ct = ct->next) { if (ct->tar && ct->tar->type == OB_ARMATURE) { break; } } - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, 1); - } + BKE_constraint_targets_flush(con, &targets, 1); if (ct) { return target_space_pchan_items; diff --git a/source/blender/makesrna/intern/rna_curves.c b/source/blender/makesrna/intern/rna_curves.c index 7cf34db4cf4..b50082056bf 100644 --- a/source/blender/makesrna/intern/rna_curves.c +++ b/source/blender/makesrna/intern/rna_curves.c @@ -292,6 +292,14 @@ static void rna_def_curves(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Surface", "Mesh object that the curves can be attached to"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + prop = RNA_def_property(srna, "surface_uv_map", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "surface_uv_map"); + RNA_def_property_ui_text(prop, + "Surface UV Map", + "The name of the attribute on the surface mesh used to define the " + "attachment of each curve"); + RNA_def_property_update(prop, 0, "rna_Curves_update_draw"); + /* Symmetry. */ prop = RNA_def_property(srna, "use_mirror_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "symmetry", CURVES_SYMMETRY_X); @@ -308,6 +316,18 @@ static void rna_def_curves(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Z", "Enable symmetry in the Z axis"); RNA_def_property_update(prop, 0, "rna_Curves_update_draw"); + prop = RNA_def_property(srna, "selection_domain", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, rna_enum_attribute_curves_domain_items); + RNA_def_property_ui_text(prop, "Selection Domain", ""); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Curves_update_data"); + + prop = RNA_def_property(srna, "use_sculpt_selection", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", CV_SCULPT_SELECTION_ENABLED); + RNA_def_property_ui_text(prop, "Use Sculpt Selection", ""); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Curves_update_draw"); + /* attributes */ rna_def_attributes_common(srna); diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 269ebe1581f..c7b713d80f5 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -257,6 +257,51 @@ static void rna_Image_file_format_set(PointerRNA *ptr, int value) } } +static void rna_UDIMTile_size_get(PointerRNA *ptr, int *values) +{ + ImageTile *tile = (ImageTile *)ptr->data; + Image *image = (Image *)ptr->owner_id; + + ImageUser image_user; + BKE_imageuser_default(&image_user); + image_user.tile = tile->tile_number; + + void *lock; + ImBuf *ibuf = BKE_image_acquire_ibuf(image, &image_user, &lock); + if (ibuf) { + values[0] = ibuf->x; + values[1] = ibuf->y; + } + else { + values[0] = 0; + values[1] = 0; + } + + BKE_image_release_ibuf(image, ibuf, lock); +} + +static int rna_UDIMTile_channels_get(PointerRNA *ptr) +{ + ImageTile *tile = (ImageTile *)ptr->data; + Image *image = (Image *)ptr->owner_id; + + ImageUser image_user; + BKE_imageuser_default(&image_user); + image_user.tile = tile->tile_number; + + int channels = 0; + + void *lock; + ImBuf *ibuf = BKE_image_acquire_ibuf(image, &image_user, &lock); + if (ibuf) { + channels = ibuf->channels; + } + + BKE_image_release_ibuf(image, ibuf, lock); + + return channels; +} + static void rna_UDIMTile_label_get(PointerRNA *ptr, char *value) { ImageTile *tile = (ImageTile *)ptr->data; @@ -826,6 +871,26 @@ static void rna_def_udim_tile(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Number", "Number of the position that this tile covers"); RNA_def_property_int_funcs(prop, NULL, "rna_UDIMTile_tile_number_set", NULL); RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, NULL); + + prop = RNA_def_int_vector( + srna, + "size", + 2, + NULL, + 0, + 0, + "Size", + "Width and height of the tile buffer in pixels, zero when image data can't be loaded", + 0, + 0); + RNA_def_property_subtype(prop, PROP_PIXEL); + RNA_def_property_int_funcs(prop, "rna_UDIMTile_size_get", NULL, NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_property(srna, "channels", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_funcs(prop, "rna_UDIMTile_channels_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Channels", "Number of channels in the tile pixels buffer"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); } static void rna_def_udim_tiles(BlenderRNA *brna, PropertyRNA *cprop) diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index 46bb0df5c11..d2b8b32eedc 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -160,11 +160,15 @@ static void rna_Image_update(Image *image, ReportList *reports) BKE_image_release_ibuf(image, ibuf, NULL); } -static void rna_Image_scale(Image *image, ReportList *reports, int width, int height) +static void rna_Image_scale(Image *image, bContext *C, ReportList *reports, int width, int height) { if (!BKE_image_scale(image, width, height)) { BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2); } + else { + BKE_image_partial_update_mark_full_update(image); + WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, image); + } } static int rna_Image_gl_load( @@ -281,7 +285,7 @@ void RNA_api_image(StructRNA *srna) func = RNA_def_function(srna, "scale", "rna_Image_scale"); RNA_def_function_ui_description(func, "Scale the buffer of the image, in pixels"); - RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_CONTEXT); parm = RNA_def_int(func, "width", 1, 1, INT_MAX, "", "Width", 1, INT_MAX); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_int(func, "height", 1, 1, INT_MAX, "", "Height", 1, INT_MAX); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 36e815716ca..d3a61412b63 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1136,7 +1136,7 @@ static int rna_MeshPoly_vertices_get_length(const PointerRNA *ptr, { const MPoly *mp = (MPoly *)ptr->data; /* NOTE: raw access uses dummy item, this _could_ crash, - * watch out for this, mface uses it but it can't work here. */ + * watch out for this, #MFace uses it but it can't work here. */ return (length[0] = mp->totloop); } diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 4c410782326..8591d4abd63 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1369,10 +1369,9 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf( Object *ob_src = dtmd->ob_source; if (ob_src) { - AttributeDomain domain = STREQ(RNA_property_identifier(prop), - "layers_vcol_vert_select_src") ? - ATTR_DOMAIN_POINT : - ATTR_DOMAIN_CORNER; + eAttrDomain domain = STREQ(RNA_property_identifier(prop), "layers_vcol_vert_select_src") ? + ATTR_DOMAIN_POINT : + ATTR_DOMAIN_CORNER; Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); @@ -1392,7 +1391,7 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf( cdata = &me_eval->ldata; } - CustomDataType types[2] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; + eCustomDataType types[2] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; int idx = 0; for (int i = 0; i < 2; i++) { @@ -1492,7 +1491,7 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_dst_itemf( Object *ob_dst = CTX_data_active_object(C); /* XXX Is this OK? */ if (ob_dst && ob_dst->data) { - CustomDataType types[2] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; + eCustomDataType types[2] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; Mesh *me_dst = ob_dst->data; CustomData *cdata = STREQ(RNA_property_identifier(prop), "layers_vcol_vert_select_dst") ? diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 8acc31cd71a..100d90df5d6 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -240,7 +240,7 @@ static int rna_SequenceEditor_sequences_all_lookup_string(PointerRNA *ptr, ID *id = ptr->owner_id; Scene *scene = (Scene *)id; - Sequence *seq = SEQ_sequence_lookup_by_name(scene, key); + Sequence *seq = SEQ_sequence_lookup_seq_by_name(scene, key); if (seq) { RNA_pointer_create(ptr->owner_id, &RNA_Sequence, seq, r_ptr); return true; @@ -289,26 +289,11 @@ static void rna_Sequence_views_format_update(Main *bmain, Scene *scene, PointerR static void do_sequence_frame_change_update(Scene *scene, Sequence *seq) { - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); - Sequence *tseq; - SEQ_time_update_sequence(scene, seqbase, seq); - - /* ensure effects are always fit in length to their input */ - - /* TODO(sergey): probably could be optimized. - * in terms skipping update of non-changing strips - */ - for (tseq = seqbase->first; tseq; tseq = tseq->next) { - if (tseq->seq1 || tseq->seq2 || tseq->seq3) { - SEQ_time_update_sequence(scene, seqbase, tseq); - } - } + ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, seq); if (SEQ_transform_test_overlap(seqbase, seq)) { - SEQ_transform_seqbase_shuffle(seqbase, seq, scene); /* XXX: BROKEN!, uses context seqbasep. */ + SEQ_transform_seqbase_shuffle(seqbase, seq, scene); } - SEQ_sort(seqbase); if (seq->type == SEQ_TYPE_SOUND_RAM) { DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); @@ -341,8 +326,8 @@ static void rna_Sequence_start_frame_final_set(PointerRNA *ptr, int value) Sequence *seq = (Sequence *)ptr->data; Scene *scene = (Scene *)ptr->owner_id; - SEQ_time_left_handle_frame_set(seq, value); - SEQ_transform_fix_single_image_seq_offsets(seq); + SEQ_time_left_handle_frame_set(scene, seq, value); + SEQ_transform_fix_single_image_seq_offsets(scene, seq); do_sequence_frame_change_update(scene, seq); SEQ_relations_invalidate_cache_composite(scene, seq); } @@ -352,8 +337,8 @@ static void rna_Sequence_end_frame_final_set(PointerRNA *ptr, int value) Sequence *seq = (Sequence *)ptr->data; Scene *scene = (Scene *)ptr->owner_id; - SEQ_time_right_handle_frame_set(seq, value); - SEQ_transform_fix_single_image_seq_offsets(seq); + SEQ_time_right_handle_frame_set(scene, seq, value); + SEQ_transform_fix_single_image_seq_offsets(scene, seq); do_sequence_frame_change_update(scene, seq); SEQ_relations_invalidate_cache_composite(scene, seq); } @@ -437,7 +422,7 @@ static void rna_Sequence_frame_length_set(PointerRNA *ptr, int value) Sequence *seq = (Sequence *)ptr->data; Scene *scene = (Scene *)ptr->owner_id; - SEQ_time_right_handle_frame_set(seq, SEQ_time_left_handle_frame_get(seq) + value); + SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(seq) + value); do_sequence_frame_change_update(scene, seq); SEQ_relations_invalidate_cache_composite(scene, seq); } @@ -459,18 +444,15 @@ static void rna_Sequence_channel_set(PointerRNA *ptr, int value) { Sequence *seq = (Sequence *)ptr->data; Scene *scene = (Scene *)ptr->owner_id; - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); + ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, seq); /* check channel increment or decrement */ const int channel_delta = (value >= seq->machine) ? 1 : -1; seq->machine = value; if (SEQ_transform_test_overlap(seqbase, seq)) { - /* XXX: BROKEN!, uses context seqbasep. */ SEQ_transform_seqbase_shuffle_ex(seqbase, seq, scene, channel_delta); } - SEQ_sort(seqbase); SEQ_relations_invalidate_cache_composite(scene, seq); } @@ -722,8 +704,6 @@ static IDProperty **rna_Sequence_idprops(PointerRNA *ptr) static bool rna_MovieSequence_reload_if_needed(ID *scene_id, Sequence *seq, Main *bmain) { Scene *scene = (Scene *)scene_id; - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); bool has_reloaded; bool can_produce_frames; @@ -731,7 +711,6 @@ static bool rna_MovieSequence_reload_if_needed(ID *scene_id, Sequence *seq, Main SEQ_add_movie_reload_if_needed(bmain, scene, seq, &has_reloaded, &can_produce_frames); if (has_reloaded && can_produce_frames) { - SEQ_time_update_sequence(scene, seqbase, seq); SEQ_relations_invalidate_cache_raw(scene, seq); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); @@ -919,9 +898,6 @@ static void rna_Sequence_filepath_update(Main *bmain, Scene *UNUSED(scene), Poin Scene *scene = (Scene *)ptr->owner_id; Sequence *seq = (Sequence *)(ptr->data); SEQ_add_reload_new_file(bmain, scene, seq, true); - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); - SEQ_time_update_sequence(scene, seqbase, seq); rna_Sequence_invalidate_raw_update(bmain, scene, ptr); } @@ -1337,8 +1313,7 @@ static void rna_Sequence_separate(ID *id, Sequence *seqm, Main *bmain) Scene *scene = (Scene *)id; /* Find the appropriate seqbase */ - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seqm); + ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, seqm); LISTBASE_FOREACH_MUTABLE (Sequence *, seq, &seqm->seqbase) { SEQ_edit_move_strip_to_seqbase(scene, &seqm->seqbase, seq, seqbase); diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 36bc50e73fb..52de98be502 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -49,20 +49,6 @@ # include "WM_api.h" -static void rna_Sequence_update_rnafunc(ID *id, Sequence *self, bool do_data) -{ - Scene *scene = (Scene *)id; - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, self); - - if (do_data) { - SEQ_time_update_recursive(scene, self); - // new_tstripdata(self); /* need 2.6x version of this. */ - } - - SEQ_time_update_sequence(scene, seqbase, self); -} - static void rna_Sequence_swap_internal(Sequence *seq_self, ReportList *reports, Sequence *seq_other) @@ -96,8 +82,7 @@ static Sequence *rna_Sequence_split( ID *id, Sequence *seq, Main *bmain, ReportList *reports, int frame, int split_method) { Scene *scene = (Scene *)id; - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); + ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, seq); const char *error_msg = NULL; Sequence *r_seq = SEQ_edit_strip_split( @@ -576,8 +561,6 @@ static void rna_Sequences_meta_remove( static StripElem *rna_SequenceElements_append(ID *id, Sequence *seq, const char *filename) { Scene *scene = (Scene *)id; - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); StripElem *se; seq->strip->stripdata = se = MEM_reallocN(seq->strip->stripdata, @@ -586,7 +569,6 @@ static StripElem *rna_SequenceElements_append(ID *id, Sequence *seq, const char BLI_strncpy(se->name, filename, sizeof(se->name)); seq->len++; - SEQ_time_update_sequence(scene, seqbase, seq); WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene); return se; @@ -595,8 +577,6 @@ static StripElem *rna_SequenceElements_append(ID *id, Sequence *seq, const char static void rna_SequenceElements_pop(ID *id, Sequence *seq, ReportList *reports, int index) { Scene *scene = (Scene *)id; - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); StripElem *new_seq, *se; if (seq->len == 1) { @@ -629,8 +609,6 @@ static void rna_SequenceElements_pop(ID *id, Sequence *seq, ReportList *reports, MEM_freeN(seq->strip->stripdata); seq->strip->stripdata = new_seq; - SEQ_time_update_sequence(scene, seqbase, seq); - WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene); } @@ -669,11 +647,6 @@ void RNA_api_sequence_strip(StructRNA *srna) {0, NULL, 0, NULL, NULL}, }; - func = RNA_def_function(srna, "update", "rna_Sequence_update_rnafunc"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Update the strip dimensions"); - parm = RNA_def_boolean(func, "data", false, "Data", "Update strip data"); - func = RNA_def_function(srna, "strip_elem_from_frame", "SEQ_render_give_stripelem"); RNA_def_function_ui_description(func, "Return the strip element from a given frame or None"); parm = RNA_def_int(func, diff --git a/source/blender/makesrna/intern/rna_sound.c b/source/blender/makesrna/intern/rna_sound.c index 2714b4157fd..e38481a845a 100644 --- a/source/blender/makesrna/intern/rna_sound.c +++ b/source/blender/makesrna/intern/rna_sound.c @@ -15,7 +15,7 @@ #include "BKE_sound.h" /* Enumeration for Audio Channels, compatible with eSoundChannels */ -const EnumPropertyItem rna_enum_audio_channels_items[] = { +static const EnumPropertyItem rna_enum_audio_channels_items[] = { {SOUND_CHANNELS_INVALID, "INVALID", ICON_NONE, "Invalid", "Invalid"}, {SOUND_CHANNELS_MONO, "MONO", ICON_NONE, "Mono", "Mono"}, {SOUND_CHANNELS_STEREO, "STEREO", ICON_NONE, "Stereo", "Stereo"}, diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index af43133c979..cae86801402 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -7818,6 +7818,12 @@ static void rna_def_spreadsheet_row_filter(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Integer Value", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL); + prop = RNA_def_property(srna, "value_int8", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "value_int"); + RNA_def_property_range(prop, -128, 127); + RNA_def_property_ui_text(prop, "8-Bit Integer Value", ""); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL); + prop = RNA_def_property(srna, "value_boolean", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SPREADSHEET_ROW_FILTER_BOOL_VALUE); RNA_def_property_ui_text(prop, "Boolean Value", ""); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 1dc2cbe9e69..3ff9e6be3ce 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -24,6 +24,7 @@ #include "rna_internal.h" +#include "WM_api.h" #include "WM_types.h" #ifdef RNA_RUNTIME @@ -123,6 +124,23 @@ static const EnumPropertyItem event_ndof_type_items[] = { }; #endif /* RNA_RUNTIME */ +/** + * Job types for use in the `bpy.app.is_job_running(job_type)` call. + * + * This is a subset of the `WM_JOB_TYPE_...` anonymous enum defined in `WM_api.h`. It is + * intentionally kept as a subset, such that by default how jobs are handled is kept as an + * "internal implementation detail" of Blender, rather than a public, reliable part of the API. + * + * This array can be expanded on a case-by-case basis, when there is a clear and testable use case. + */ +const EnumPropertyItem rna_enum_wm_job_type_items[] = { + {WM_JOB_TYPE_RENDER, "RENDER", 0, "Regular rendering", ""}, + {WM_JOB_TYPE_RENDER_PREVIEW, "RENDER_PREVIEW", 0, "Rendering previews", ""}, + {WM_JOB_TYPE_OBJECT_BAKE, "OBJECT_BAKE", 0, "Object Baking", ""}, + {WM_JOB_TYPE_COMPOSITE, "COMPOSITE", 0, "Compositing", ""}, + {0, NULL, 0, NULL, NULL}, +}; + const EnumPropertyItem rna_enum_event_type_items[] = { /* - Note we abuse 'tooltip' message here to store a 'compact' form of some (too) long names. * - Intentionally excluded: #CAPSLOCKKEY, #UNKNOWNKEY. @@ -898,7 +916,7 @@ static void rna_wmKeyMapItem_map_type_set(PointerRNA *ptr, int value) /** * Assumes value to be an enum from rna_enum_event_type_items. - * Function makes sure keymodifiers are only valid keys, ESC keeps it unaltered. + * Function makes sure key-modifiers are only valid keys, ESC keeps it unaltered. */ static void rna_wmKeyMapItem_keymodifier_set(PointerRNA *ptr, int value) { diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index 5da65510399..b9f36d35ee8 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -23,6 +23,7 @@ #include "wm_cursors.h" #include "wm_event_types.h" +#include "WM_api.h" #include "WM_types.h" #include "rna_internal.h" /* own include */ diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index c44a4e0b438..02aa5254e55 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -328,7 +328,7 @@ static void mesh_merge_transform(Mesh *result, ml->e += cap_edges_index; } - /* set origindex */ + /* Set #CD_ORIGINDEX. */ index_orig = CustomData_get_layer(&result->vdata, CD_ORIGINDEX); if (index_orig) { copy_vn_i(index_orig + cap_verts_index, cap_nverts, ORIGINDEX_NONE); diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc index d47f2a130e3..07504d91fea 100644 --- a/source/blender/modifiers/intern/MOD_boolean.cc +++ b/source/blender/modifiers/intern/MOD_boolean.cc @@ -223,7 +223,7 @@ static BMesh *BMD_mesh_bm_create( Mesh *mesh, Object *object, Mesh *mesh_operand_ob, Object *operand_ob, bool *r_is_flip) { #ifdef DEBUG_TIME - SCOPED_TIMER(__func__) + SCOPED_TIMER(__func__); #endif *r_is_flip = (is_negative_m4(object->obmat) != is_negative_m4(operand_ob->obmat)); @@ -270,7 +270,7 @@ static void BMD_mesh_intersection(BMesh *bm, bool is_flip) { #ifdef DEBUG_TIME - SCOPED_TIMER(__func__) + SCOPED_TIMER(__func__); #endif BooleanModifierData *bmd = (BooleanModifierData *)md; @@ -399,7 +399,7 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd, Vector<Array<short>> material_remaps; # ifdef DEBUG_TIME - SCOPED_TIMER(__func__) + SCOPED_TIMER(__func__); # endif if ((bmd->flag & eBooleanModifierFlag_Object) && bmd->object == nullptr) { @@ -470,7 +470,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * #endif #ifdef DEBUG_TIME - SCOPED_TIMER(__func__) + SCOPED_TIMER(__func__); #endif if (bmd->flag & eBooleanModifierFlag_Object) { @@ -518,24 +518,29 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * Mesh *mesh_operand_ob = BKE_modifier_get_evaluated_mesh_from_evaluated_object(operand_ob, false); - if (mesh_operand_ob) { - /* XXX This is utterly non-optimal, we may go from a bmesh to a mesh back to a bmesh! - * But for 2.90 better not try to be smart here. */ - BKE_mesh_wrapper_ensure_mdata(mesh_operand_ob); + if (mesh_operand_ob == nullptr) { + continue; + } - bool is_flip; - BMesh *bm = BMD_mesh_bm_create(mesh, object, mesh_operand_ob, operand_ob, &is_flip); + /* XXX This is utterly non-optimal, we may go from a bmesh to a mesh back to a bmesh! + * But for 2.90 better not try to be smart here. */ + BKE_mesh_wrapper_ensure_mdata(mesh_operand_ob); - BMD_mesh_intersection(bm, md, ctx, mesh_operand_ob, object, operand_ob, is_flip); + bool is_flip; + BMesh *bm = BMD_mesh_bm_create(result, object, mesh_operand_ob, operand_ob, &is_flip); - /* Needed for multiple objects to work. */ - BMeshToMeshParams bmesh_to_mesh_params{}; - bmesh_to_mesh_params.calc_object_remap = false; - BM_mesh_bm_to_me(nullptr, bm, mesh, &bmesh_to_mesh_params); + BMD_mesh_intersection(bm, md, ctx, mesh_operand_ob, object, operand_ob, is_flip); + /* Needed for multiple objects to work. */ + if (result == mesh) { result = BKE_mesh_from_bmesh_for_eval_nomain(bm, nullptr, mesh); - BM_mesh_free(bm); } + else { + BMeshToMeshParams bmesh_to_mesh_params{}; + bmesh_to_mesh_params.calc_object_remap = false; + BM_mesh_bm_to_me(nullptr, bm, result, &bmesh_to_mesh_params); + } + BM_mesh_free(bm); } } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index 1891ac5df7c..6b0578c77f1 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -83,17 +83,17 @@ static void requiredDataMask(Object *UNUSED(ob), if (pmd->canvas) { DynamicPaintSurface *surface = pmd->canvas->surfaces.first; for (; surface; surface = surface->next) { - /* tface */ + /* UV's: #CD_MLOOPUV. */ if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ || surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) { r_cddata_masks->lmask |= CD_MASK_MLOOPUV; } - /* mcol */ + /* Vertex Colors: #CD_PROP_BYTE_COLOR. */ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT || surface->init_color_type == MOD_DPAINT_INITIAL_VERTEXCOLOR) { r_cddata_masks->lmask |= CD_MASK_PROP_BYTE_COLOR; } - /* CD_MDEFORMVERT */ + /* Vertex Weights: #CD_MDEFORMVERT. */ if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; } diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index d76a750f7e8..8e85cb1bfb3 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -897,7 +897,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, { Mesh *explode, *mesh = to_explode; MFace *mf = NULL, *mface; - /* ParticleSettings *part=psmd->psys->part; */ /* UNUSED */ + // ParticleSettings *part=psmd->psys->part; /* UNUSED */ ParticleSimulationData sim = {NULL}; ParticleData *pa = NULL, *pars = psmd->psys->particles; ParticleKey state, birth; @@ -906,7 +906,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, float *vertco = NULL, imat[4][4]; float rot[4]; float ctime; - /* float timestep; */ + // float timestep; const int *facepa = emd->facepa; int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0; int i, v, u; @@ -923,7 +923,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, sim.psys = psmd->psys; sim.psmd = psmd; - /* timestep = psys_get_timestep(&sim); */ + // timestep = psys_get_timestep(&sim); ctime = BKE_scene_ctime_get(scene); diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index e0105e4962d..73db56186de 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -119,8 +119,8 @@ using blender::nodes::InputSocketFieldType; using blender::threading::EnumerableThreadSpecific; using namespace blender::fn::multi_function_types; using namespace blender::nodes::derived_node_tree_types; +using geo_log::eNamedAttrUsage; using geo_log::GeometryAttributeInfo; -using geo_log::NamedAttributeUsage; static void initData(ModifierData *md) { @@ -755,6 +755,7 @@ static void initialize_group_input(NodesModifierData &nmd, { const bNodeSocketType &socket_type = *socket.typeinfo(); const bNodeSocket &bsocket = *socket.bsocket(); + const eNodeSocketDatatype socket_data_type = static_cast<eNodeSocketDatatype>(bsocket.type); if (nmd.settings.properties == nullptr) { socket_type.get_geometry_nodes_cpp_value(bsocket, r_value); return; @@ -771,8 +772,7 @@ static void initialize_group_input(NodesModifierData &nmd, } if (!input_has_attribute_toggle(*nmd.node_group, socket.index())) { - init_socket_cpp_value_from_property( - *property, static_cast<eNodeSocketDatatype>(bsocket.type), r_value); + init_socket_cpp_value_from_property(*property, socket_data_type, r_value); return; } @@ -781,14 +781,17 @@ static void initialize_group_input(NodesModifierData &nmd, const IDProperty *property_attribute_name = IDP_GetPropertyFromGroup( nmd.settings.properties, (socket.identifier() + attribute_name_suffix).c_str()); if (property_use_attribute == nullptr || property_attribute_name == nullptr) { - init_socket_cpp_value_from_property( - *property, static_cast<eNodeSocketDatatype>(bsocket.type), r_value); + init_socket_cpp_value_from_property(*property, socket_data_type, r_value); return; } const bool use_attribute = IDP_Int(property_use_attribute) != 0; if (use_attribute) { const StringRef attribute_name{IDP_String(property_attribute_name)}; + if (!blender::bke::allow_procedural_attribute_access(attribute_name)) { + init_socket_cpp_value_from_property(*property, socket_data_type, r_value); + return; + } auto attribute_input = std::make_shared<blender::bke::AttributeFieldInput>( attribute_name, *socket_type.base_cpp_type); GField attribute_field{std::move(attribute_input), 0}; @@ -799,8 +802,7 @@ static void initialize_group_input(NodesModifierData &nmd, cpp_type->construct_from_field(r_value, std::move(attribute_field)); } else { - init_socket_cpp_value_from_property( - *property, static_cast<eNodeSocketDatatype>(bsocket.type), r_value); + init_socket_cpp_value_from_property(*property, socket_data_type, r_value); } } @@ -919,7 +921,7 @@ struct OutputAttributeInfo { struct OutputAttributeToStore { GeometryComponentType component_type; - AttributeDomain domain; + eAttrDomain domain; StringRefNull name; GMutableSpan data; }; @@ -928,10 +930,10 @@ struct OutputAttributeToStore { * The output attributes are organized based on their domain, because attributes on the same domain * can be evaluated together. */ -static MultiValueMap<AttributeDomain, OutputAttributeInfo> find_output_attributes_to_store( +static MultiValueMap<eAttrDomain, OutputAttributeInfo> find_output_attributes_to_store( const NodesModifierData &nmd, const NodeRef &output_node, Span<GMutablePointer> output_values) { - MultiValueMap<AttributeDomain, OutputAttributeInfo> outputs_by_domain; + MultiValueMap<eAttrDomain, OutputAttributeInfo> outputs_by_domain; for (const InputSocketRef *socket : output_node.inputs().drop_front(1).drop_back(1)) { if (!socket_type_has_attribute_toggle(*socket->bsocket())) { continue; @@ -946,6 +948,9 @@ static MultiValueMap<AttributeDomain, OutputAttributeInfo> find_output_attribute if (attribute_name.is_empty()) { continue; } + if (!blender::bke::allow_procedural_attribute_access(attribute_name)) { + continue; + } const int index = socket->index(); const GPointer value = output_values[index]; @@ -955,7 +960,7 @@ static MultiValueMap<AttributeDomain, OutputAttributeInfo> find_output_attribute const bNodeSocket *interface_socket = (const bNodeSocket *)BLI_findlink( &nmd.node_group->outputs, socket->index()); - const AttributeDomain domain = (AttributeDomain)interface_socket->attribute_domain; + const eAttrDomain domain = (eAttrDomain)interface_socket->attribute_domain; OutputAttributeInfo output_info; output_info.field = std::move(field); output_info.name = attribute_name; @@ -970,7 +975,7 @@ static MultiValueMap<AttributeDomain, OutputAttributeInfo> find_output_attribute */ static Vector<OutputAttributeToStore> compute_attributes_to_store( const GeometrySet &geometry, - const MultiValueMap<AttributeDomain, OutputAttributeInfo> &outputs_by_domain) + const MultiValueMap<eAttrDomain, OutputAttributeInfo> &outputs_by_domain) { Vector<OutputAttributeToStore> attributes_to_store; for (const GeometryComponentType component_type : {GEO_COMPONENT_TYPE_MESH, @@ -982,7 +987,7 @@ static Vector<OutputAttributeToStore> compute_attributes_to_store( } const GeometryComponent &component = *geometry.get_component_for_read(component_type); for (const auto item : outputs_by_domain.items()) { - const AttributeDomain domain = item.key; + const eAttrDomain domain = item.key; const Span<OutputAttributeInfo> outputs_info = item.value; if (!component.attribute_domain_supported(domain)) { continue; @@ -1011,7 +1016,8 @@ static void store_computed_output_attributes( { for (const OutputAttributeToStore &store : attributes_to_store) { GeometryComponent &component = geometry.get_component_for_write(store.component_type); - const CustomDataType data_type = blender::bke::cpp_type_to_custom_data_type(store.data.type()); + const eCustomDataType data_type = blender::bke::cpp_type_to_custom_data_type( + store.data.type()); const std::optional<AttributeMetaData> meta_data = component.attribute_get_meta_data( store.name); @@ -1052,7 +1058,7 @@ static void store_output_attributes(GeometrySet &geometry, { /* All new attribute values have to be computed before the geometry is actually changed. This is * necessary because some fields might depend on attributes that are overwritten. */ - MultiValueMap<AttributeDomain, OutputAttributeInfo> outputs_by_domain = + MultiValueMap<eAttrDomain, OutputAttributeInfo> outputs_by_domain = find_output_attributes_to_store(nmd, output_node, output_values); Vector<OutputAttributeToStore> attributes_to_store = compute_attributes_to_store( geometry, outputs_by_domain); @@ -1431,6 +1437,14 @@ static void add_attribute_search_button(const bContext &C, nullptr, attribute_search_exec_fn, nullptr); + + char *attribute_name = RNA_string_get_alloc( + md_ptr, rna_path_attribute_name.c_str(), nullptr, 0, nullptr); + const bool access_allowed = blender::bke::allow_procedural_attribute_access(attribute_name); + MEM_freeN(attribute_name); + if (!access_allowed) { + UI_but_flag_enable(but, UI_BUT_REDALERT); + } } static void add_attribute_search_or_value_buttons(const bContext &C, @@ -1651,7 +1665,7 @@ static void internal_dependencies_panel_draw(const bContext *UNUSED(C), Panel *p return; } const geo_log::ModifierLog &log = *static_cast<geo_log::ModifierLog *>(nmd->runtime_eval_log); - Map<std::string, NamedAttributeUsage> usage_by_attribute; + Map<std::string, eNamedAttrUsage> usage_by_attribute; log.foreach_node_log([&](const geo_log::NodeLog &node_log) { for (const geo_log::UsedNamedAttribute &used_attribute : node_log.used_named_attributes()) { usage_by_attribute.lookup_or_add_as(used_attribute.name, @@ -1666,7 +1680,7 @@ static void internal_dependencies_panel_draw(const bContext *UNUSED(C), Panel *p struct NameWithUsage { StringRefNull name; - NamedAttributeUsage usage; + eNamedAttrUsage usage; }; Vector<NameWithUsage> sorted_used_attribute; @@ -1681,20 +1695,20 @@ static void internal_dependencies_panel_draw(const bContext *UNUSED(C), Panel *p for (const NameWithUsage &attribute : sorted_used_attribute) { const StringRefNull attribute_name = attribute.name; - const NamedAttributeUsage usage = attribute.usage; + const eNamedAttrUsage usage = attribute.usage; /* #uiLayoutRowWithHeading doesn't seem to work in this case. */ uiLayout *split = uiLayoutSplit(layout, 0.4f, false); std::stringstream ss; Vector<std::string> usages; - if ((usage & NamedAttributeUsage::Read) != NamedAttributeUsage::None) { + if ((usage & eNamedAttrUsage::Read) != eNamedAttrUsage::None) { usages.append(TIP_("Read")); } - if ((usage & NamedAttributeUsage::Write) != NamedAttributeUsage::None) { + if ((usage & eNamedAttrUsage::Write) != eNamedAttrUsage::None) { usages.append(TIP_("Write")); } - if ((usage & NamedAttributeUsage::Remove) != NamedAttributeUsage::None) { + if ((usage & eNamedAttrUsage::Remove) != eNamedAttrUsage::None) { usages.append(TIP_("Remove")); } for (const int i : usages.index_range()) { diff --git a/source/blender/modifiers/intern/MOD_particlesystem.cc b/source/blender/modifiers/intern/MOD_particlesystem.cc index c6a606360e3..f410915cad8 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.cc +++ b/source/blender/modifiers/intern/MOD_particlesystem.cc @@ -306,9 +306,10 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* srna */ &RNA_ParticleSystemModifier, /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | - eModifierTypeFlag_UsesPointCache /* | - eModifierTypeFlag_SupportsEditmode | - eModifierTypeFlag_EnableInEditmode */ + eModifierTypeFlag_UsesPointCache +#if 0 + | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode +#endif , /* icon */ ICON_MOD_PARTICLES, diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh index bac4d0165e9..b82c05f33be 100644 --- a/source/blender/nodes/NOD_geometry_exec.hh +++ b/source/blender/nodes/NOD_geometry_exec.hh @@ -40,7 +40,7 @@ using fn::FieldInput; using fn::FieldOperation; using fn::GField; using fn::ValueOrField; -using geometry_nodes_eval_log::NamedAttributeUsage; +using geometry_nodes_eval_log::eNamedAttrUsage; using geometry_nodes_eval_log::NodeWarningType; /** @@ -298,52 +298,11 @@ class GeoNodeExecParams { */ void error_message_add(const NodeWarningType type, std::string message) const; - /** - * Creates a read-only attribute based on node inputs. The method automatically detects which - * input socket with the given name is available. - * - * \note This will add an error message if the string socket is active and - * the input attribute does not exist. - */ - GVArray get_input_attribute(const StringRef name, - const GeometryComponent &component, - AttributeDomain domain, - const CustomDataType type, - const void *default_value) const; - - template<typename T> - VArray<T> get_input_attribute(const StringRef name, - const GeometryComponent &component, - const AttributeDomain domain, - const T &default_value) const - { - const CustomDataType type = bke::cpp_type_to_custom_data_type(CPPType::get<T>()); - GVArray varray = this->get_input_attribute(name, component, domain, type, &default_value); - return varray.typed<T>(); - } - - /** - * Get the type of an input property or the associated constant socket types with the - * same names. Fall back to the default value if no attribute exists with the name. - */ - CustomDataType get_input_attribute_data_type(const StringRef name, - const GeometryComponent &component, - const CustomDataType default_type) const; - - /** - * If any of the corresponding input sockets are attributes instead of single values, - * use the highest priority attribute domain from among them. - * Otherwise return the default domain. - */ - AttributeDomain get_highest_priority_input_domain(Span<std::string> names, - const GeometryComponent &component, - AttributeDomain default_domain) const; - std::string attribute_producer_name() const; void set_default_remaining_outputs(); - void used_named_attribute(std::string attribute_name, NamedAttributeUsage usage); + void used_named_attribute(std::string attribute_name, eNamedAttrUsage usage); private: /* Utilities for detecting common errors at when using this class. */ diff --git a/source/blender/nodes/NOD_geometry_nodes_eval_log.hh b/source/blender/nodes/NOD_geometry_nodes_eval_log.hh index 2917861f084..05c97c3903d 100644 --- a/source/blender/nodes/NOD_geometry_nodes_eval_log.hh +++ b/source/blender/nodes/NOD_geometry_nodes_eval_log.hh @@ -90,8 +90,8 @@ class GFieldValueLog : public ValueLog { struct GeometryAttributeInfo { std::string name; /** Can be empty when #name does not actually exist on a geometry yet. */ - std::optional<AttributeDomain> domain; - std::optional<CustomDataType> data_type; + std::optional<eAttrDomain> domain; + std::optional<eCustomDataType> data_type; }; /** Contains information about a geometry set. In most cases this does not store the entire @@ -171,17 +171,17 @@ struct ValueOfSockets { destruct_ptr<ValueLog> value; }; -enum class NamedAttributeUsage { +enum class eNamedAttrUsage { None = 0, Read = 1 << 0, Write = 1 << 1, Remove = 1 << 2, }; -ENUM_OPERATORS(NamedAttributeUsage, NamedAttributeUsage::Remove); +ENUM_OPERATORS(eNamedAttrUsage, eNamedAttrUsage::Remove); struct UsedNamedAttribute { std::string name; - NamedAttributeUsage usage; + eNamedAttrUsage usage; }; struct NodeWithUsedNamedAttribute { @@ -219,7 +219,7 @@ class LocalGeoLogger { void log_multi_value_socket(DSocket socket, Span<GPointer> values); void log_node_warning(DNode node, NodeWarningType type, std::string message); void log_execution_time(DNode node, std::chrono::microseconds exec_time); - void log_used_named_attribute(DNode node, std::string attribute_name, NamedAttributeUsage usage); + void log_used_named_attribute(DNode node, std::string attribute_name, eNamedAttrUsage usage); /** * Log a message that will be displayed in the node editor next to the node. * This should only be used for debugging purposes and not to display information to users. diff --git a/source/blender/nodes/function/nodes/node_fn_random_value.cc b/source/blender/nodes/function/nodes/node_fn_random_value.cc index a0942ced1be..360695299cb 100644 --- a/source/blender/nodes/function/nodes/node_fn_random_value.cc +++ b/source/blender/nodes/function/nodes/node_fn_random_value.cc @@ -57,7 +57,7 @@ static void fn_node_random_value_init(bNodeTree *UNUSED(tree), bNode *node) static void fn_node_random_value_update(bNodeTree *ntree, bNode *node) { const NodeRandomValue &storage = node_storage(*node); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); bNodeSocket *sock_min_vector = (bNodeSocket *)node->inputs.first; bNodeSocket *sock_max_vector = sock_min_vector->next; @@ -86,7 +86,7 @@ static void fn_node_random_value_update(bNodeTree *ntree, bNode *node) nodeSetSocketAvailability(ntree, sock_out_bool, data_type == CD_PROP_BOOL); } -static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSocket &socket) +static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket) { switch (socket.type) { case SOCK_FLOAT: @@ -106,7 +106,7 @@ static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSock static void fn_node_random_value_gather_link_search(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - const std::optional<CustomDataType> type = node_type_from_other_socket(params.other_socket()); + const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket()); if (!type) { return; } @@ -137,7 +137,7 @@ static void fn_node_random_value_gather_link_search(GatherLinkSearchOpParams &pa static void fn_node_random_value_build_multi_function(NodeMultiFunctionBuilder &builder) { const NodeRandomValue &storage = node_storage(builder.node()); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); switch (data_type) { case CD_PROP_FLOAT3: { diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc index 7f9ec329efd..8f673d2264e 100644 --- a/source/blender/nodes/geometry/node_geometry_util.cc +++ b/source/blender/nodes/geometry/node_geometry_util.cc @@ -14,7 +14,7 @@ namespace blender::nodes { -std::optional<CustomDataType> node_data_type_to_custom_data_type(const eNodeSocketDatatype type) +std::optional<eCustomDataType> node_data_type_to_custom_data_type(const eNodeSocketDatatype type) { switch (type) { case SOCK_FLOAT: @@ -34,7 +34,7 @@ std::optional<CustomDataType> node_data_type_to_custom_data_type(const eNodeSock } } -std::optional<CustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket) +std::optional<eCustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket) { return node_data_type_to_custom_data_type(static_cast<eNodeSocketDatatype>(socket.type)); } diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index 8f20da66c3b..d261928d1b8 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -70,13 +70,13 @@ void copy_point_attributes_based_on_mask(const GeometryComponent &in_component, * component. If no component can work with the domain, then `error_message` is set to true. */ void separate_geometry(GeometrySet &geometry_set, - AttributeDomain domain, + eAttrDomain domain, GeometryNodeDeleteGeometryMode mode, const Field<bool> &selection_field, bool invert, bool &r_is_error); -std::optional<CustomDataType> node_data_type_to_custom_data_type(eNodeSocketDatatype type); -std::optional<CustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket); +std::optional<eCustomDataType> node_data_type_to_custom_data_type(eNodeSocketDatatype type); +std::optional<eCustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket); } // namespace blender::nodes diff --git a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc index b29831ceeb6..a7404af8564 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc @@ -87,7 +87,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node) static void node_update(bNodeTree *ntree, bNode *node) { const NodeAccumulateField &storage = node_storage(*node); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); bNodeSocket *sock_in_vector = (bNodeSocket *)node->inputs.first; bNodeSocket *sock_in_float = sock_in_vector->next; @@ -123,7 +123,7 @@ static void node_update(bNodeTree *ntree, bNode *node) enum class AccumulationMode { Leading = 0, Trailing = 1 }; -static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSocket &socket) +static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket) { switch (socket.type) { case SOCK_FLOAT: @@ -141,7 +141,7 @@ static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSock static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { - const std::optional<CustomDataType> type = node_type_from_other_socket(params.other_socket()); + const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket()); if (!type) { return; } @@ -196,11 +196,11 @@ template<typename T> class AccumulateFieldInput final : public GeometryFieldInpu private: Field<T> input_; Field<int> group_index_; - AttributeDomain source_domain_; + eAttrDomain source_domain_; AccumulationMode accumulation_mode_; public: - AccumulateFieldInput(const AttributeDomain source_domain, + AccumulateFieldInput(const eAttrDomain source_domain, Field<T> input, Field<int> group_index, AccumulationMode accumulation_mode) @@ -213,7 +213,7 @@ template<typename T> class AccumulateFieldInput final : public GeometryFieldInpu } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { const GeometryComponentFieldContext field_context{component, source_domain_}; @@ -287,10 +287,10 @@ template<typename T> class TotalFieldInput final : public GeometryFieldInput { private: Field<T> input_; Field<int> group_index_; - AttributeDomain source_domain_; + eAttrDomain source_domain_; public: - TotalFieldInput(const AttributeDomain source_domain, Field<T> input, Field<int> group_index) + TotalFieldInput(const eAttrDomain source_domain, Field<T> input, Field<int> group_index) : GeometryFieldInput(CPPType::get<T>(), "Total Value"), input_(input), group_index_(group_index), @@ -299,7 +299,7 @@ template<typename T> class TotalFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { const GeometryComponentFieldContext field_context{component, source_domain_}; @@ -365,8 +365,8 @@ template<typename T> std::string identifier_suffix() static void node_geo_exec(GeoNodeExecParams params) { const NodeAccumulateField &storage = node_storage(params.node()); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); - const AttributeDomain source_domain = static_cast<AttributeDomain>(storage.domain); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); + const eAttrDomain source_domain = static_cast<eAttrDomain>(storage.domain); Field<int> group_index_field = params.extract_input<Field<int>>("Group Index"); attribute_math::convert_to_static_type(data_type, [&](auto dummy) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc index 16967d32673..496fb081d6b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc @@ -50,7 +50,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node) static void node_update(bNodeTree *ntree, bNode *node) { const NodeGeometryAttributeCapture &storage = node_storage(*node); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); bNodeSocket *socket_value_geometry = (bNodeSocket *)node->inputs.first; bNodeSocket *socket_value_vector = socket_value_geometry->next; @@ -86,7 +86,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) search_link_ops_for_declarations(params, declaration.outputs().take_front(1)); const bNodeType &node_type = params.node_type(); - const std::optional<CustomDataType> type = node_data_type_to_custom_data_type( + const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type( (eNodeSocketDatatype)params.other_socket().type); if (type && *type != CD_PROP_STRING) { if (params.in_out() == SOCK_OUT) { @@ -108,14 +108,14 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) static void try_capture_field_on_geometry(GeometryComponent &component, const AttributeIDRef &attribute_id, - const AttributeDomain domain, + const eAttrDomain domain, const GField &field) { GeometryComponentFieldContext field_context{component, domain}; const int domain_num = component.attribute_domain_num(domain); const IndexMask mask{IndexMask(domain_num)}; - const CustomDataType data_type = bke::cpp_type_to_custom_data_type(field.cpp_type()); + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(field.cpp_type()); OutputAttribute output_attribute = component.attribute_try_get_for_output_only( attribute_id, domain, data_type); @@ -126,7 +126,7 @@ static void try_capture_field_on_geometry(GeometryComponent &component, output_attribute.save(); } -static StringRefNull identifier_suffix(CustomDataType data_type) +static StringRefNull identifier_suffix(eCustomDataType data_type) { switch (data_type) { case CD_PROP_FLOAT: @@ -158,8 +158,8 @@ static void node_geo_exec(GeoNodeExecParams params) } const NodeGeometryAttributeCapture &storage = node_storage(params.node()); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); - const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); + const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain); const std::string output_identifier = "Attribute" + identifier_suffix(data_type); diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc index c7f65a68d60..35404725998 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc @@ -77,7 +77,7 @@ static void node_update(bNodeTree *ntree, bNode *node) bNodeSocket *socket_vector_std = socket_vector_range->next; bNodeSocket *socket_vector_variance = socket_vector_std->next; - const CustomDataType data_type = static_cast<CustomDataType>(node->custom1); + const eCustomDataType data_type = static_cast<eCustomDataType>(node->custom1); nodeSetSocketAvailability(ntree, socket_float_attr, data_type == CD_PROP_FLOAT); nodeSetSocketAvailability(ntree, socket_float_mean, data_type == CD_PROP_FLOAT); @@ -100,7 +100,7 @@ static void node_update(bNodeTree *ntree, bNode *node) nodeSetSocketAvailability(ntree, socket_vector_variance, data_type == CD_PROP_FLOAT3); } -static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSocket &socket) +static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket) { switch (socket.type) { case SOCK_FLOAT: @@ -121,7 +121,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) const NodeDeclaration &declaration = *params.node_type().fixed_declaration; search_link_ops_for_declarations(params, declaration.inputs().take_front(2)); - const std::optional<CustomDataType> type = node_type_from_other_socket(params.other_socket()); + const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket()); if (!type) { return; } @@ -184,8 +184,8 @@ static void node_geo_exec(GeoNodeExecParams params) { GeometrySet geometry_set = params.get_input<GeometrySet>("Geometry"); const bNode &node = params.node(); - const CustomDataType data_type = static_cast<CustomDataType>(node.custom1); - const AttributeDomain domain = static_cast<AttributeDomain>(node.custom2); + const eCustomDataType data_type = static_cast<eCustomDataType>(node.custom1); + const eAttrDomain domain = static_cast<eAttrDomain>(node.custom2); Vector<const GeometryComponent *> components = geometry_set.get_components_for_read(); const Field<bool> selection_field = params.get_input<Field<bool>>("Selection"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc index bbc8758952d..b52bf2571b5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc @@ -41,7 +41,7 @@ class EndpointFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc index dc2b9d40894..5ef20f03f28 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc @@ -84,7 +84,7 @@ class HandleTypeFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask mask) const final { if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc index ae36248b573..8401c94be4b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc @@ -107,7 +107,7 @@ static Array<float> curve_length_point_domain(const bke::CurvesGeometry &curves) static VArray<float> construct_curve_parameter_varray(const bke::CurvesGeometry &curves, const IndexMask UNUSED(mask), - const AttributeDomain domain) + const eAttrDomain domain) { VArray<bool> cyclic = curves.cyclic(); @@ -146,7 +146,7 @@ static VArray<float> construct_curve_parameter_varray(const bke::CurvesGeometry static VArray<float> construct_curve_length_parameter_varray(const bke::CurvesGeometry &curves, const IndexMask UNUSED(mask), - const AttributeDomain domain) + const eAttrDomain domain) { curves.ensure_evaluated_lengths(); @@ -165,7 +165,7 @@ static VArray<float> construct_curve_length_parameter_varray(const bke::CurvesGe static VArray<int> construct_index_on_spline_varray(const bke::CurvesGeometry &curves, const IndexMask UNUSED(mask), - const AttributeDomain domain) + const eAttrDomain domain) { if (domain == ATTR_DOMAIN_POINT) { Array<int> result(curves.points_num()); @@ -191,7 +191,7 @@ class CurveParameterFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask mask) const final { if (component.type() == GEO_COMPONENT_TYPE_CURVE) { @@ -225,7 +225,7 @@ class CurveLengthParameterFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask mask) const final { if (component.type() == GEO_COMPONENT_TYPE_CURVE) { @@ -259,7 +259,7 @@ class IndexOnSplineFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask mask) const final { if (component.type() == GEO_COMPONENT_TYPE_CURVE) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc index 73b2c400e90..7d83b4b3ecb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc @@ -124,7 +124,7 @@ static Array<int> calculate_spline_point_offsets(GeoNodeExecParams ¶ms, */ static GMutableSpan ensure_point_attribute(PointCloudComponent &points, const AttributeIDRef &attribute_id, - const CustomDataType data_type) + const eCustomDataType data_type) { points.attribute_try_create(attribute_id, ATTR_DOMAIN_POINT, data_type, AttributeInitDefault()); WriteAttributeLookup attribute = points.attribute_try_get_for_write(attribute_id); diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc index 99edc4d298c..5350896e93d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc @@ -57,7 +57,7 @@ static IndexMask index_mask_indices(Span<bool> mask, const bool invert, Vector<i static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes, const GeometryComponent &in_component, GeometryComponent &result_component, - const Span<AttributeDomain> domains) + const Span<eAttrDomain> domains) { for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; @@ -70,7 +70,7 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes if (!domains.contains(attribute.domain)) { continue; } - const CustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type()); + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type()); OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only( attribute_id, attribute.domain, data_type); @@ -96,7 +96,7 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKind> &attributes, const GeometryComponent &in_component, GeometryComponent &result_component, - const AttributeDomain domain, + const eAttrDomain domain, const IndexMask mask) { for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { @@ -110,7 +110,7 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin if (domain != attribute.domain) { continue; } - const CustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type()); + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type()); OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only( attribute_id, attribute.domain, data_type); @@ -132,7 +132,7 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind> &attributes, const GeometryComponent &in_component, GeometryComponent &result_component, - const AttributeDomain domain, + const eAttrDomain domain, const Span<int> index_map) { for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { @@ -146,7 +146,7 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind if (domain != attribute.domain) { continue; } - const CustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type()); + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type()); OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only( attribute_id, attribute.domain, data_type); @@ -400,7 +400,7 @@ static SplinePtr spline_delete(const Spline &spline, const IndexMask mask) static std::unique_ptr<CurveEval> curve_separate(const CurveEval &input_curve, const Span<bool> selection, - const AttributeDomain selection_domain, + const eAttrDomain selection_domain, const bool invert) { Span<SplinePtr> input_splines = input_curve.splines(); @@ -463,7 +463,7 @@ static std::unique_ptr<CurveEval> curve_separate(const CurveEval &input_curve, static void separate_curve_selection(GeometrySet &geometry_set, const Field<bool> &selection_field, - const AttributeDomain selection_domain, + const eAttrDomain selection_domain, const bool invert) { const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>(); @@ -987,7 +987,7 @@ static void do_mesh_separation(GeometrySet &geometry_set, const MeshComponent &in_component, const VArray_Span<bool> &selection, const bool invert, - const AttributeDomain domain, + const eAttrDomain domain, const GeometryNodeDeleteGeometryMode mode) { /* Needed in all cases. */ @@ -1230,7 +1230,7 @@ static void do_mesh_separation(GeometrySet &geometry_set, static void separate_mesh_selection(GeometrySet &geometry_set, const Field<bool> &selection_field, - const AttributeDomain selection_domain, + const eAttrDomain selection_domain, const GeometryNodeDeleteGeometryMode mode, const bool invert) { @@ -1263,7 +1263,7 @@ static void separate_mesh_selection(GeometrySet &geometry_set, namespace blender::nodes { void separate_geometry(GeometrySet &geometry_set, - const AttributeDomain domain, + const eAttrDomain domain, const GeometryNodeDeleteGeometryMode mode, const Field<bool> &selection_field, const bool invert, @@ -1320,7 +1320,7 @@ static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { const bNode *node = static_cast<bNode *>(ptr->data); const NodeGeometryDeleteGeometry &storage = node_storage(*node); - const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain); + const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain); uiItemR(layout, ptr, "domain", 0, "", ICON_NONE); /* Only show the mode when it is relevant. */ @@ -1345,7 +1345,7 @@ static void node_geo_exec(GeoNodeExecParams params) const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection"); const NodeGeometryDeleteGeometry &storage = node_storage(params.node()); - const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain); + const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain); const GeometryNodeDeleteGeometryMode mode = (GeometryNodeDeleteGeometryMode)storage.mode; if (domain == ATTR_DOMAIN_INSTANCE) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc index c242cfd5cf3..f95601813a3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc @@ -247,7 +247,7 @@ BLI_NOINLINE static void eliminate_points_based_on_mask(const Span<bool> elimina BLI_NOINLINE static void interpolate_attribute(const Mesh &mesh, const Span<float3> bary_coords, const Span<int> looptri_indices, - const AttributeDomain source_domain, + const eAttrDomain source_domain, const GVArray &source_data, GMutableSpan output_data) { @@ -293,7 +293,7 @@ BLI_NOINLINE static void propagate_existing_attributes( for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; - const CustomDataType output_data_type = entry.value.data_type; + const eCustomDataType output_data_type = entry.value.data_type; ReadAttributeLookup source_attribute = mesh_component.attribute_try_get_for_read(attribute_id); if (!source_attribute) { @@ -396,7 +396,7 @@ static Array<float> calc_full_density_factors_with_selection(const MeshComponent const Field<float> &density_field, const Field<bool> &selection_field) { - const AttributeDomain attribute_domain = ATTR_DOMAIN_CORNER; + const eAttrDomain attribute_domain = ATTR_DOMAIN_CORNER; GeometryComponentFieldContext field_context{component, attribute_domain}; const int domain_num = component.attribute_domain_num(attribute_domain); diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc index dcd9bcfb034..52156b59c51 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc @@ -153,7 +153,7 @@ static void transfer_attributes( continue; } - AttributeDomain out_domain; + eAttrDomain out_domain; if (src_attribute.domain == ATTR_DOMAIN_FACE) { out_domain = ATTR_DOMAIN_POINT; } @@ -164,7 +164,7 @@ static void transfer_attributes( /* Edges and Face Corners. */ out_domain = src_attribute.domain; } - const CustomDataType data_type = bke::cpp_type_to_custom_data_type( + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type( src_attribute.varray.type()); OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only( attribute_id, out_domain, data_type); diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index ebf0c450605..cde40319388 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -144,7 +144,7 @@ static void threaded_id_offset_copy(const Span<int> offsets, /** Create the copy indices for the duplication domain. */ static void create_duplicate_index_attribute(GeometryComponent &component, - const AttributeDomain output_domain, + const eAttrDomain output_domain, const IndexMask selection, const IndexAttributes &attribute_outputs, const Span<int> offsets) @@ -208,8 +208,8 @@ static void copy_point_attributes_without_id(GeometrySet &geometry_set, if (!src_attribute || src_attribute.domain != ATTR_DOMAIN_POINT) { continue; } - AttributeDomain out_domain = src_attribute.domain; - const CustomDataType data_type = bke::cpp_type_to_custom_data_type( + eAttrDomain out_domain = src_attribute.domain; + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type( src_attribute.varray.type()); OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only( attribute_id, out_domain, data_type); @@ -254,8 +254,8 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set, continue; } - AttributeDomain out_domain = src_attribute.domain; - const CustomDataType data_type = bke::cpp_type_to_custom_data_type( + eAttrDomain out_domain = src_attribute.domain; + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type( src_attribute.varray.type()); OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only( attribute_id, out_domain, data_type); @@ -435,8 +435,8 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set, continue; } - AttributeDomain out_domain = src_attribute.domain; - const CustomDataType data_type = bke::cpp_type_to_custom_data_type( + eAttrDomain out_domain = src_attribute.domain; + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type( src_attribute.varray.type()); OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only( attribute_id, out_domain, data_type); @@ -648,8 +648,8 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set, continue; } - const AttributeDomain out_domain = src_attribute.domain; - const CustomDataType data_type = bke::cpp_type_to_custom_data_type( + const eAttrDomain out_domain = src_attribute.domain; + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type( src_attribute.varray.type()); OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only( attribute_id, out_domain, data_type); @@ -701,12 +701,12 @@ static void copy_stable_id_edges(const Mesh &mesh, VArray_Span<int> src{src_attribute.varray.typed<int>()}; MutableSpan<int> dst = dst_attribute.as_span<int>(); threading::parallel_for(IndexRange(selection.size()), 1024, [&](IndexRange range) { - for (const int i_edge : range) { - const IndexRange edge_range = range_for_offsets_index(edge_offsets, i_edge); + for (const int i_selection : range) { + const IndexRange edge_range = range_for_offsets_index(edge_offsets, i_selection); if (edge_range.size() == 0) { continue; } - const MEdge &edge = edges[i_edge]; + const MEdge &edge = edges[selection[i_selection]]; const IndexRange vert_range = {edge_range.start() * 2, edge_range.size() * 2}; dst[vert_range[0]] = src[edge.v1]; @@ -750,9 +750,9 @@ static void duplicate_edges(GeometrySet &geometry_set, Array<int> vert_orig_indices(edge_offsets.last() * 2); threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) { - for (const int i_edge : range) { - const MEdge &edge = edges[i_edge]; - const IndexRange edge_range = range_for_offsets_index(edge_offsets, i_edge); + for (const int i_selection : range) { + const MEdge &edge = edges[selection[i_selection]]; + const IndexRange edge_range = range_for_offsets_index(edge_offsets, i_selection); const IndexRange vert_range(edge_range.start() * 2, edge_range.size() * 2); for (const int i_duplicate : IndexRange(edge_range.size())) { @@ -763,8 +763,8 @@ static void duplicate_edges(GeometrySet &geometry_set, }); threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) { - for (const int i_edge : range) { - const IndexRange edge_range = range_for_offsets_index(edge_offsets, i_edge); + for (const int i_selection : range) { + const IndexRange edge_range = range_for_offsets_index(edge_offsets, i_selection); const IndexRange vert_range(edge_range.start() * 2, edge_range.size() * 2); for (const int i_duplicate : IndexRange(edge_range.size())) { MEdge &new_edge = new_edges[edge_range[i_duplicate]]; @@ -849,8 +849,8 @@ static void duplicate_points_curve(GeometrySet &geometry_set, continue; } - AttributeDomain domain = src_attribute.domain; - const CustomDataType data_type = bke::cpp_type_to_custom_data_type( + eAttrDomain domain = src_attribute.domain; + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type( src_attribute.varray.type()); OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only( attribute_id, domain, data_type); @@ -1103,7 +1103,7 @@ static void node_geo_exec(GeoNodeExecParams params) GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); const NodeGeometryDuplicateElements &storage = node_storage(params.node()); - const AttributeDomain duplicate_domain = AttributeDomain(storage.domain); + const eAttrDomain duplicate_domain = eAttrDomain(storage.domain); Field<int> count_field = params.extract_input<Field<int>>("Amount"); Field<bool> selection_field = params.extract_input<Field<bool>>("Selection"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index 1f16e8d55bd..3eca92e37a3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -63,7 +63,7 @@ struct AttributeOutputs { static void save_selection_as_attribute(MeshComponent &component, const AnonymousAttributeID *id, - const AttributeDomain domain, + const eAttrDomain domain, const IndexMask selection) { BLI_assert(!component.attribute_exists(id)); @@ -145,6 +145,34 @@ static void expand_mesh(Mesh &mesh, BKE_mesh_update_customdata_pointers(&mesh, false); } +static CustomData &get_customdata(Mesh &mesh, const eAttrDomain domain) +{ + switch (domain) { + case ATTR_DOMAIN_POINT: + return mesh.vdata; + case ATTR_DOMAIN_EDGE: + return mesh.edata; + case ATTR_DOMAIN_FACE: + return mesh.pdata; + case ATTR_DOMAIN_CORNER: + return mesh.ldata; + default: + BLI_assert_unreachable(); + return mesh.vdata; + } +} + +static MutableSpan<int> get_orig_index_layer(Mesh &mesh, const eAttrDomain domain) +{ + MeshComponent component; + component.replace(&mesh, GeometryOwnershipType::ReadOnly); + CustomData &custom_data = get_customdata(mesh, domain); + if (int *orig_indices = static_cast<int *>(CustomData_get_layer(&custom_data, CD_ORIGINDEX))) { + return {orig_indices, component.attribute_domain_num(domain)}; + } + return {}; +} + static MEdge new_edge(const int v1, const int v2) { MEdge edge; @@ -292,6 +320,9 @@ static void extrude_mesh_vertices(MeshComponent &component, }); }); + MutableSpan<int> vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT); + vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE); + if (attribute_outputs.top_id) { save_selection_as_attribute( component, attribute_outputs.top_id.get(), ATTR_DOMAIN_POINT, new_vert_range); @@ -615,6 +646,13 @@ static void extrude_mesh_edges(MeshComponent &component, }); } + MutableSpan<int> vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT); + vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE); + + MutableSpan<int> edge_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_EDGE); + edge_orig_indices.slice(connect_edge_range).fill(ORIGINDEX_NONE); + edge_orig_indices.slice(duplicate_edge_range).fill(ORIGINDEX_NONE); + if (attribute_outputs.top_id) { save_selection_as_attribute( component, attribute_outputs.top_id.get(), ATTR_DOMAIN_EDGE, duplicate_edge_range); @@ -983,6 +1021,17 @@ static void extrude_mesh_face_regions(MeshComponent &component, }); } + MutableSpan<int> vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT); + vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE); + + MutableSpan<int> edge_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_EDGE); + edge_orig_indices.slice(connect_edge_range).fill(ORIGINDEX_NONE); + edge_orig_indices.slice(new_inner_edge_range).fill(ORIGINDEX_NONE); + edge_orig_indices.slice(boundary_edge_range).fill(ORIGINDEX_NONE); + + MutableSpan<int> poly_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_FACE); + poly_orig_indices.slice(side_poly_range).fill(ORIGINDEX_NONE); + if (attribute_outputs.top_id) { save_selection_as_attribute( component, attribute_outputs.top_id.get(), ATTR_DOMAIN_FACE, poly_selection); @@ -1232,6 +1281,16 @@ static void extrude_individual_mesh_faces(MeshComponent &component, } }); + MutableSpan<int> vert_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_POINT); + vert_orig_indices.slice(new_vert_range).fill(ORIGINDEX_NONE); + + MutableSpan<int> edge_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_EDGE); + edge_orig_indices.slice(connect_edge_range).fill(ORIGINDEX_NONE); + edge_orig_indices.slice(duplicate_edge_range).fill(ORIGINDEX_NONE); + + MutableSpan<int> poly_orig_indices = get_orig_index_layer(mesh, ATTR_DOMAIN_FACE); + poly_orig_indices.slice(side_poly_range).fill(ORIGINDEX_NONE); + /* Finally update each extruded polygon's loops to point to the new edges and vertices. * This must be done last, because they were used to find original indices for attribute * interpolation before. Alternatively an original index array could be built for each domain. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc index bf956f3b83d..58281df43d3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc @@ -42,7 +42,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node) static void node_update(bNodeTree *ntree, bNode *node) { - const CustomDataType data_type = static_cast<CustomDataType>(node->custom2); + const eCustomDataType data_type = static_cast<eCustomDataType>(node->custom2); bNodeSocket *sock_index = static_cast<bNodeSocket *>(node->inputs.first); bNodeSocket *sock_in_float = sock_index->next; @@ -74,10 +74,10 @@ class FieldAtIndex final : public GeometryFieldInput { private: Field<int> index_field_; GField value_field_; - AttributeDomain value_field_domain_; + eAttrDomain value_field_domain_; public: - FieldAtIndex(Field<int> index_field, GField value_field, AttributeDomain value_field_domain) + FieldAtIndex(Field<int> index_field, GField value_field, eAttrDomain value_field_domain) : GeometryFieldInput(value_field.cpp_type(), "Field at Index"), index_field_(std::move(index_field)), value_field_(std::move(value_field)), @@ -86,7 +86,7 @@ class FieldAtIndex final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask mask) const final { const GeometryComponentFieldContext value_field_context{component, value_field_domain_}; @@ -125,7 +125,7 @@ class FieldAtIndex final : public GeometryFieldInput { } }; -static StringRefNull identifier_suffix(CustomDataType data_type) +static StringRefNull identifier_suffix(eCustomDataType data_type) { switch (data_type) { case CD_PROP_BOOL: @@ -147,8 +147,8 @@ static StringRefNull identifier_suffix(CustomDataType data_type) static void node_geo_exec(GeoNodeExecParams params) { const bNode &node = params.node(); - const AttributeDomain domain = static_cast<AttributeDomain>(node.custom1); - const CustomDataType data_type = static_cast<CustomDataType>(node.custom2); + const eAttrDomain domain = static_cast<eAttrDomain>(node.custom1); + const eCustomDataType data_type = static_cast<eCustomDataType>(node.custom2); Field<int> index_field = params.extract_input<Field<int>>("Index"); attribute_math::convert_to_static_type(data_type, [&](auto dummy) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc index 3ba1378abe1..da249278867 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc @@ -26,7 +26,7 @@ class HandlePositionFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask mask) const final { if (component.type() != GEO_COMPONENT_TYPE_CURVE) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc index 60640bcb112..f27e0305c7d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc @@ -61,7 +61,7 @@ class AngleFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() != GEO_COMPONENT_TYPE_MESH) { @@ -115,7 +115,7 @@ class SignedAngleFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() != GEO_COMPONENT_TYPE_MESH) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc index 92172ce7ebd..cbc2ebc3e68 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc @@ -25,7 +25,7 @@ class EdgeNeighborCountFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() == GEO_COMPONENT_TYPE_MESH) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc index 213a692d80f..6201ad26bfb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc @@ -29,7 +29,7 @@ enum VertexNumber { VERTEX_ONE, VERTEX_TWO }; static VArray<int> construct_edge_vertices_gvarray(const MeshComponent &component, const VertexNumber vertex, - const AttributeDomain domain) + const eAttrDomain domain) { const Mesh *mesh = component.get_for_read(); if (mesh == nullptr) { @@ -58,7 +58,7 @@ class EdgeVerticesFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() == GEO_COMPONENT_TYPE_MESH) { @@ -85,7 +85,7 @@ class EdgeVerticesFieldInput final : public GeometryFieldInput { static VArray<float3> construct_edge_positions_gvarray(const MeshComponent &component, const VertexNumber vertex, - const AttributeDomain domain) + const eAttrDomain domain) { const Mesh *mesh = component.get_for_read(); if (mesh == nullptr) { @@ -120,7 +120,7 @@ class EdgePositionFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() == GEO_COMPONENT_TYPE_MESH) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc index 6f58d28100a..7a0e3e37a65 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc @@ -17,7 +17,7 @@ static void node_declare(NodeDeclarationBuilder &b) } static VArray<float> construct_face_area_gvarray(const MeshComponent &component, - const AttributeDomain domain) + const eAttrDomain domain) { const Mesh *mesh = component.get_for_read(); if (mesh == nullptr) { @@ -41,7 +41,7 @@ class FaceAreaFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() == GEO_COMPONENT_TYPE_MESH) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc index 62af0476057..c400760f902 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc @@ -34,7 +34,7 @@ class PlanarFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, [[maybe_unused]] IndexMask mask) const final { if (component.type() != GEO_COMPONENT_TYPE_MESH) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc index 9968c53f649..67a21cb06f0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc @@ -20,7 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b) } static VArray<int> construct_neighbor_count_gvarray(const MeshComponent &component, - const AttributeDomain domain) + const eAttrDomain domain) { const Mesh *mesh = component.get_for_read(); if (mesh == nullptr) { @@ -53,7 +53,7 @@ class FaceNeighborCountFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() == GEO_COMPONENT_TYPE_MESH) { @@ -76,7 +76,7 @@ class FaceNeighborCountFieldInput final : public GeometryFieldInput { }; static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component, - const AttributeDomain domain) + const eAttrDomain domain) { const Mesh *mesh = component.get_for_read(); if (mesh == nullptr) { @@ -98,7 +98,7 @@ class FaceVertexCountFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() == GEO_COMPONENT_TYPE_MESH) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc index 8e3a9b6769d..bd57924d685 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc @@ -30,7 +30,7 @@ class IslandFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() != GEO_COMPONENT_TYPE_MESH) { @@ -78,7 +78,7 @@ class IslandCountFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() != GEO_COMPONENT_TYPE_MESH) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc index b81016eda18..62b3f9d0e92 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc @@ -21,7 +21,7 @@ static void node_declare(NodeDeclarationBuilder &b) } static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component, - const AttributeDomain domain) + const eAttrDomain domain) { const Mesh *mesh = component.get_for_read(); if (mesh == nullptr) { @@ -47,7 +47,7 @@ class VertexCountFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() == GEO_COMPONENT_TYPE_MESH) { @@ -70,7 +70,7 @@ class VertexCountFieldInput final : public GeometryFieldInput { }; static VArray<int> construct_face_count_gvarray(const MeshComponent &component, - const AttributeDomain domain) + const eAttrDomain domain) { const Mesh *mesh = component.get_for_read(); if (mesh == nullptr) { @@ -96,7 +96,7 @@ class VertexFaceCountFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() == GEO_COMPONENT_TYPE_MESH) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc index 553ea6cfcf0..122c7b352c7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc @@ -37,7 +37,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node) static void node_update(bNodeTree *ntree, bNode *node) { const NodeGeometryInputNamedAttribute &storage = node_storage(*node); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); bNodeSocket *socket_vector = (bNodeSocket *)node->outputs.first; bNodeSocket *socket_float = socket_vector->next; @@ -58,7 +58,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) search_link_ops_for_declarations(params, declaration.inputs()); if (params.in_out() == SOCK_OUT) { - const std::optional<CustomDataType> type = node_data_type_to_custom_data_type( + const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type( static_cast<eNodeSocketDatatype>(params.other_socket().type)); if (type && *type != CD_PROP_STRING) { /* The input and output sockets have the same name. */ @@ -74,7 +74,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) static void node_geo_exec(GeoNodeExecParams params) { const NodeGeometryInputNamedAttribute &storage = node_storage(params.node()); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); const std::string name = params.extract_input<std::string>("Name"); @@ -88,7 +88,7 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - params.used_named_attribute(name, NamedAttributeUsage::Read); + params.used_named_attribute(name, eNamedAttrUsage::Read); switch (data_type) { case CD_PROP_FLOAT: diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc index 84d773ff8eb..def82eefca5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc @@ -17,7 +17,7 @@ static void node_declare(NodeDeclarationBuilder &b) */ static VArray<int> construct_curve_point_count_gvarray(const CurveComponent &component, - const AttributeDomain domain) + const eAttrDomain domain) { if (!component.has_curves()) { return {}; @@ -47,7 +47,7 @@ class SplineCountFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() == GEO_COMPONENT_TYPE_CURVE) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc index 039d6b69585..f5831941094 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc @@ -64,7 +64,7 @@ static Array<float3> curve_tangent_point_domain(const bke::CurvesGeometry &curve } static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &component, - const AttributeDomain domain) + const eAttrDomain domain) { if (!component.has_curves()) { return {}; @@ -101,7 +101,7 @@ class TangentFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask UNUSED(mask)) const final { if (component.type() == GEO_COMPONENT_TYPE_CURVE) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc index 12582f9e9c6..21ef8765e43 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc @@ -49,7 +49,7 @@ static void add_instances_from_component( const GeoNodeExecParams ¶ms, const Map<AttributeIDRef, AttributeKind> &attributes_to_propagate) { - const AttributeDomain domain = ATTR_DOMAIN_POINT; + const eAttrDomain domain = ATTR_DOMAIN_POINT; const int domain_num = src_component.attribute_domain_num(domain); VArray<bool> pick_instance; diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc index 2067086c298..0c56b0e9804 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc @@ -47,8 +47,8 @@ static Map<AttributeIDRef, AttributeMetaData> get_final_attribute_info( static void fill_new_attribute(Span<const GeometryComponent *> src_components, const AttributeIDRef &attribute_id, - const CustomDataType data_type, - const AttributeDomain domain, + const eCustomDataType data_type, + const eAttrDomain domain, GMutableSpan dst_span) { const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(data_type); diff --git a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc index c245260f259..5875606da97 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc @@ -51,7 +51,7 @@ class MaterialSelectionFieldInput final : public GeometryFieldInput { } GVArray get_varray_for_context(const GeometryComponent &component, - const AttributeDomain domain, + const eAttrDomain domain, IndexMask mask) const final { if (component.type() != GEO_COMPONENT_TYPE_MESH) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc index 6b23b685549..7463eb01471 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc @@ -58,7 +58,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, Field<float3> &position_field, Field<float> &radius_field, Field<bool> &selection_field, - const AttributeDomain domain) + const eAttrDomain domain) { const MeshComponent *mesh_component = geometry_set.get_component_for_read<MeshComponent>(); if (mesh_component == nullptr) { @@ -105,7 +105,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; - const CustomDataType data_type = entry.value.data_type; + const eCustomDataType data_type = entry.value.data_type; GVArray src = mesh_component->attribute_get_for_read(attribute_id, domain, data_type); OutputAttribute dst = point_component.attribute_try_get_for_output_only( attribute_id, ATTR_DOMAIN_POINT, data_type); diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc index 577b001fd06..00b3d167755 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc @@ -59,7 +59,7 @@ static void geometry_set_points_to_vertices(GeometrySet &geometry_set, for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; - const CustomDataType data_type = entry.value.data_type; + const eCustomDataType data_type = entry.value.data_type; GVArray src = point_component->attribute_get_for_read( attribute_id, ATTR_DOMAIN_POINT, data_type); OutputAttribute dst = mesh_component.attribute_try_get_for_output_only( diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc index 0c30d50076f..a92cee2d066 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc @@ -70,7 +70,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node) static void node_update(bNodeTree *ntree, bNode *node) { const NodeGeometryRaycast &storage = node_storage(*node); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); bNodeSocket *socket_vector = (bNodeSocket *)BLI_findlink(&node->inputs, 1); bNodeSocket *socket_float = socket_vector->next; @@ -104,7 +104,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) search_link_ops_for_declarations(params, declaration.inputs().take_back(3)); search_link_ops_for_declarations(params, declaration.outputs().take_front(4)); - const std::optional<CustomDataType> type = node_data_type_to_custom_data_type( + const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type( (eNodeSocketDatatype)params.other_socket().type); if (type && *type != CD_PROP_STRING) { /* The input and output sockets have the same name. */ @@ -215,7 +215,7 @@ class RaycastFunction : public fn::MultiFunction { /* Always evaluate the target domain data on the face corner domain because it contains the most * information. Eventually this could be exposed as an option or determined automatically from * the field inputs for better performance. */ - const AttributeDomain domain_ = ATTR_DOMAIN_CORNER; + const eAttrDomain domain_ = ATTR_DOMAIN_CORNER; fn::MFSignature signature_; @@ -320,7 +320,7 @@ class RaycastFunction : public fn::MultiFunction { } }; -static GField get_input_attribute_field(GeoNodeExecParams ¶ms, const CustomDataType data_type) +static GField get_input_attribute_field(GeoNodeExecParams ¶ms, const eCustomDataType data_type) { switch (data_type) { case CD_PROP_FLOAT: @@ -387,7 +387,7 @@ static void node_geo_exec(GeoNodeExecParams params) GeometrySet target = params.extract_input<GeometrySet>("Target Geometry"); const NodeGeometryRaycast &storage = node_storage(params.node()); const GeometryNodeRaycastMapMode mapping = (GeometryNodeRaycastMapMode)storage.mapping; - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); if (target.is_empty()) { params.set_default_remaining_outputs(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc index ecda35f6363..da42b8c5ee0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc @@ -55,7 +55,7 @@ static void node_geo_exec(GeoNodeExecParams params) }); if (attribute_exists && !cannot_delete) { - params.used_named_attribute(name, NamedAttributeUsage::Remove); + params.used_named_attribute(name, eNamedAttrUsage::Remove); } if (!attribute_exists) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc index 7923ad6264d..698efa8865d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc @@ -397,7 +397,7 @@ static void scale_edges_on_axis(MeshComponent &mesh_component, const AxisScaleFi static void node_geo_exec(GeoNodeExecParams params) { const bNode &node = params.node(); - const AttributeDomain domain = static_cast<AttributeDomain>(node.custom1); + const eAttrDomain domain = static_cast<eAttrDomain>(node.custom1); const GeometryNodeScaleElementsMode scale_mode = static_cast<GeometryNodeScaleElementsMode>( node.custom2); diff --git a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc index a48d422e4c0..22712c873a3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc @@ -43,7 +43,7 @@ static void node_geo_exec(GeoNodeExecParams params) const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection"); const NodeGeometrySeparateGeometry &storage = node_storage(params.node()); - const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain); + const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain); auto separate_geometry_maybe_recursively = [&](GeometrySet &geometry_set, bool invert) { bool is_error; diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc index ec95f9a89f5..87d48daddea 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc @@ -16,9 +16,9 @@ static void set_id_in_component(GeometryComponent &component, const Field<bool> &selection_field, const Field<int> &id_field) { - const AttributeDomain domain = (component.type() == GEO_COMPONENT_TYPE_INSTANCES) ? - ATTR_DOMAIN_INSTANCE : - ATTR_DOMAIN_POINT; + const eAttrDomain domain = (component.type() == GEO_COMPONENT_TYPE_INSTANCES) ? + ATTR_DOMAIN_INSTANCE : + ATTR_DOMAIN_POINT; GeometryComponentFieldContext field_context{component, domain}; const int domain_num = component.attribute_domain_num(domain); if (domain_num == 0) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index caf33108716..e9ed87e552f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -25,7 +25,7 @@ static void node_declare(NodeDeclarationBuilder &b) static void set_computed_position_and_offset(GeometryComponent &component, const VArray<float3> &in_positions, const VArray<float3> &in_offsets, - const AttributeDomain domain, + const eAttrDomain domain, const IndexMask selection) { @@ -139,9 +139,8 @@ static void set_position_in_component(GeometryComponent &component, const Field<float3> &position_field, const Field<float3> &offset_field) { - AttributeDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ? - ATTR_DOMAIN_INSTANCE : - ATTR_DOMAIN_POINT; + eAttrDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ? ATTR_DOMAIN_INSTANCE : + ATTR_DOMAIN_POINT; GeometryComponentFieldContext field_context{component, domain}; const int domain_num = component.attribute_domain_num(domain); if (domain_num == 0) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc index 669740f27cb..7ccdae2e5a6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc @@ -45,7 +45,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node) static void node_update(bNodeTree *ntree, bNode *node) { const NodeGeometryStoreNamedAttribute &storage = node_storage(*node); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); bNodeSocket *socket_geometry = (bNodeSocket *)node->inputs.first; bNodeSocket *socket_name = socket_geometry->next; @@ -69,7 +69,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) search_link_ops_for_declarations(params, declaration.inputs().take_front(2)); if (params.in_out() == SOCK_OUT) { - const std::optional<CustomDataType> type = node_data_type_to_custom_data_type( + const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type( static_cast<eNodeSocketDatatype>(params.other_socket().type)); if (type && *type != CD_PROP_STRING) { /* The input and output sockets have the same name. */ @@ -84,7 +84,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) static void try_capture_field_on_geometry(GeometryComponent &component, const StringRef name, - const AttributeDomain domain, + const eAttrDomain domain, const GField &field) { GeometryComponentFieldContext field_context{component, domain}; @@ -92,7 +92,7 @@ static void try_capture_field_on_geometry(GeometryComponent &component, const IndexMask mask{IndexMask(domain_num)}; const CPPType &type = field.cpp_type(); - const CustomDataType data_type = bke::cpp_type_to_custom_data_type(type); + const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(type); /* Could avoid allocating a new buffer if: * - We are writing to an attribute that exists already. @@ -137,11 +137,11 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - params.used_named_attribute(name, NamedAttributeUsage::Write); + params.used_named_attribute(name, eNamedAttrUsage::Write); const NodeGeometryStoreNamedAttribute &storage = node_storage(params.node()); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); - const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); + const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain); GField field; switch (data_type) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc index dca214660c8..0af6c76feaf 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc @@ -81,7 +81,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node) static void node_update(bNodeTree *ntree, bNode *node) { const NodeGeometryTransferAttribute &storage = node_storage(*node); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode) storage.mode; @@ -123,7 +123,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) search_link_ops_for_declarations(params, declaration.inputs().take_back(2)); search_link_ops_for_declarations(params, declaration.inputs().take_front(1)); - const std::optional<CustomDataType> type = node_data_type_to_custom_data_type( + const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type( (eNodeSocketDatatype)params.other_socket().type); if (type && *type != CD_PROP_STRING) { /* The input and output sockets have the same name. */ @@ -356,7 +356,7 @@ void copy_with_indices_and_comparison(const VArray<T> &src_1, static bool component_is_available(const GeometrySet &geometry, const GeometryComponentType type, - const AttributeDomain domain) + const eAttrDomain domain) { if (!geometry.has(type)) { return false; @@ -383,7 +383,7 @@ class NearestInterpolatedTransferFunction : public fn::MultiFunction { * future, it should be possible to use the most complex domain required by the field inputs, to * simplify sampling and avoid domain conversions. */ - AttributeDomain domain_ = ATTR_DOMAIN_CORNER; + eAttrDomain domain_ = ATTR_DOMAIN_CORNER; fn::MFSignature signature_; @@ -449,7 +449,7 @@ class NearestInterpolatedTransferFunction : public fn::MultiFunction { class NearestTransferFunction : public fn::MultiFunction { GeometrySet source_; GField src_field_; - AttributeDomain domain_; + eAttrDomain domain_; fn::MFSignature signature_; @@ -466,7 +466,7 @@ class NearestTransferFunction : public fn::MultiFunction { const GVArray *point_data_; public: - NearestTransferFunction(GeometrySet geometry, GField src_field, AttributeDomain domain) + NearestTransferFunction(GeometrySet geometry, GField src_field, eAttrDomain domain) : source_(std::move(geometry)), src_field_(std::move(src_field)), domain_(domain) { source_.ensure_owns_direct_data(); @@ -599,7 +599,7 @@ class NearestTransferFunction : public fn::MultiFunction { }; static const GeometryComponent *find_source_component(const GeometrySet &geometry, - const AttributeDomain domain) + const eAttrDomain domain) { /* Choose the other component based on a consistent order, rather than some more complicated * heuristic. This is the same order visible in the spreadsheet and used in the ray-cast node. */ @@ -624,7 +624,7 @@ static const GeometryComponent *find_source_component(const GeometrySet &geometr class IndexTransferFunction : public fn::MultiFunction { GeometrySet src_geometry_; GField src_field_; - AttributeDomain domain_; + eAttrDomain domain_; fn::MFSignature signature_; @@ -633,7 +633,7 @@ class IndexTransferFunction : public fn::MultiFunction { const GVArray *src_data_ = nullptr; public: - IndexTransferFunction(GeometrySet geometry, GField src_field, const AttributeDomain domain) + IndexTransferFunction(GeometrySet geometry, GField src_field, const eAttrDomain domain) : src_geometry_(std::move(geometry)), src_field_(std::move(src_field)), domain_(domain) { src_geometry_.ensure_owns_direct_data(); @@ -684,7 +684,7 @@ class IndexTransferFunction : public fn::MultiFunction { } }; -static GField get_input_attribute_field(GeoNodeExecParams ¶ms, const CustomDataType data_type) +static GField get_input_attribute_field(GeoNodeExecParams ¶ms, const eCustomDataType data_type) { switch (data_type) { case CD_PROP_FLOAT: @@ -737,8 +737,8 @@ static void node_geo_exec(GeoNodeExecParams params) const NodeGeometryTransferAttribute &storage = node_storage(params.node()); const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode) storage.mode; - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); - const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); + const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain); GField field = get_input_attribute_field(params, data_type); diff --git a/source/blender/nodes/geometry/nodes/node_geo_viewer.cc b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc index 8e9d7b0e46d..6979693e215 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_viewer.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc @@ -39,7 +39,7 @@ static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE); } -static eNodeSocketDatatype custom_data_type_to_socket_type(const CustomDataType type) +static eNodeSocketDatatype custom_data_type_to_socket_type(const eCustomDataType type) { switch (type) { case CD_PROP_FLOAT: @@ -61,7 +61,7 @@ static eNodeSocketDatatype custom_data_type_to_socket_type(const CustomDataType static void node_update(bNodeTree *ntree, bNode *node) { const NodeGeometryViewer &storage = node_storage(*node); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); const eNodeSocketDatatype socket_type = custom_data_type_to_socket_type(data_type); LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { @@ -82,7 +82,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) ED_spreadsheet_context_paths_set_geometry_node(bmain, snode, &viewer_node); }; - const std::optional<CustomDataType> type = node_socket_to_custom_data_type( + const std::optional<eCustomDataType> type = node_socket_to_custom_data_type( params.other_socket()); if (params.in_out() == SOCK_OUT) { /* The viewer node only has inputs. */ diff --git a/source/blender/nodes/intern/geometry_nodes_eval_log.cc b/source/blender/nodes/intern/geometry_nodes_eval_log.cc index 9a316190720..85dfdf03b82 100644 --- a/source/blender/nodes/intern/geometry_nodes_eval_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_eval_log.cc @@ -495,7 +495,7 @@ void LocalGeoLogger::log_execution_time(DNode node, std::chrono::microseconds ex void LocalGeoLogger::log_used_named_attribute(DNode node, std::string attribute_name, - NamedAttributeUsage usage) + eNamedAttrUsage usage) { used_named_attributes_.append({node, {std::move(attribute_name), usage}}); } diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc index abbfe4b823d..b7c5f9570e4 100644 --- a/source/blender/nodes/intern/node_common.cc +++ b/source/blender/nodes/intern/node_common.cc @@ -156,7 +156,8 @@ static void group_verify_socket_list(bNodeTree &node_tree, bNode &node, const ListBase &interface_sockets, ListBase &verify_lb, - const eNodeSocketInOut in_out) + const eNodeSocketInOut in_out, + const bool ensure_extend_socket_exists) { ListBase old_sockets = verify_lb; BLI_listbase_clear(&verify_lb); @@ -177,6 +178,17 @@ static void group_verify_socket_list(bNodeTree &node_tree, } } + if (ensure_extend_socket_exists) { + bNodeSocket *last_socket = static_cast<bNodeSocket *>(old_sockets.last); + if (last_socket != nullptr && STREQ(last_socket->identifier, "__extend__")) { + BLI_remlink(&old_sockets, last_socket); + BLI_addtail(&verify_lb, last_socket); + } + else { + nodeAddSocket(&node_tree, &node, in_out, "NodeSocketVirtual", "__extend__", ""); + } + } + /* Remove leftover sockets that didn't match the node group's interface. */ LISTBASE_FOREACH_MUTABLE (bNodeSocket *, unused_socket, &old_sockets) { nodeRemoveSocket(&node_tree, &node, unused_socket); @@ -195,8 +207,8 @@ void node_group_update(struct bNodeTree *ntree, struct bNode *node) } else { bNodeTree *ngroup = (bNodeTree *)node->id; - group_verify_socket_list(*ntree, *node, ngroup->inputs, node->inputs, SOCK_IN); - group_verify_socket_list(*ntree, *node, ngroup->outputs, node->outputs, SOCK_OUT); + group_verify_socket_list(*ntree, *node, ngroup->inputs, node->inputs, SOCK_IN, false); + group_verify_socket_list(*ntree, *node, ngroup->outputs, node->outputs, SOCK_OUT, false); } } @@ -484,15 +496,7 @@ void node_group_input_update(bNodeTree *ntree, bNode *node) } BLI_freelistN(&tmplinks); - - /* check inputs and outputs, and remove or insert them */ - { - /* value_in_out inverted for interface nodes to get correct socket value_property */ - group_verify_socket_list(*ntree, *node, ntree->inputs, node->outputs, SOCK_OUT); - - /* add virtual extension socket */ - nodeAddSocket(ntree, node, SOCK_OUT, "NodeSocketVirtual", "__extend__", ""); - } + group_verify_socket_list(*ntree, *node, ntree->inputs, node->outputs, SOCK_OUT, true); } void register_node_type_group_input() @@ -582,15 +586,7 @@ void node_group_output_update(bNodeTree *ntree, bNode *node) } BLI_freelistN(&tmplinks); - - /* check inputs and outputs, and remove or insert them */ - { - /* value_in_out inverted for interface nodes to get correct socket value_property */ - group_verify_socket_list(*ntree, *node, ntree->outputs, node->inputs, SOCK_IN); - - /* add virtual extension socket */ - nodeAddSocket(ntree, node, SOCK_IN, "NodeSocketVirtual", "__extend__", ""); - } + group_verify_socket_list(*ntree, *node, ntree->outputs, node->inputs, SOCK_IN, true); } void register_node_type_group_output() diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc index 9aee3ddcce7..56e9c9f0496 100644 --- a/source/blender/nodes/intern/node_geometry_exec.cc +++ b/source/blender/nodes/intern/node_geometry_exec.cc @@ -24,7 +24,7 @@ void GeoNodeExecParams::error_message_add(const NodeWarningType type, std::strin } void GeoNodeExecParams::used_named_attribute(std::string attribute_name, - const NamedAttributeUsage usage) + const eNamedAttrUsage usage) { if (provider_->logger == nullptr) { return; @@ -110,137 +110,6 @@ const bNodeSocket *GeoNodeExecParams::find_available_socket(const StringRef name return nullptr; } -GVArray GeoNodeExecParams::get_input_attribute(const StringRef name, - const GeometryComponent &component, - const AttributeDomain domain, - const CustomDataType type, - const void *default_value) const -{ - const bNodeSocket *found_socket = this->find_available_socket(name); - BLI_assert(found_socket != nullptr); /* There should always be available socket for the name. */ - const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(type); - const int64_t domain_num = component.attribute_domain_num(domain); - - if (default_value == nullptr) { - default_value = cpp_type->default_value(); - } - - if (found_socket == nullptr) { - return GVArray::ForSingle(*cpp_type, domain_num, default_value); - } - - if (found_socket->type == SOCK_STRING) { - const std::string name = this->get_input<std::string>(found_socket->identifier); - /* Try getting the attribute without the default value. */ - GVArray attribute = component.attribute_try_get_for_read(name, domain, type); - if (attribute) { - return attribute; - } - - /* If the attribute doesn't exist, use the default value and output an error message - * (except when the field is empty, to avoid spamming error messages, and not when - * the domain is empty and we don't expect an attribute anyway). */ - if (!name.empty() && component.attribute_domain_num(domain) != 0) { - this->error_message_add(NodeWarningType::Error, - TIP_("No attribute with name \"") + name + "\""); - } - return GVArray::ForSingle(*cpp_type, domain_num, default_value); - } - const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions(); - if (found_socket->type == SOCK_FLOAT) { - const float value = this->get_input<float>(found_socket->identifier); - BUFFER_FOR_CPP_TYPE_VALUE(*cpp_type, buffer); - conversions.convert_to_uninitialized(CPPType::get<float>(), *cpp_type, &value, buffer); - return GVArray::ForSingle(*cpp_type, domain_num, buffer); - } - if (found_socket->type == SOCK_INT) { - const int value = this->get_input<int>(found_socket->identifier); - BUFFER_FOR_CPP_TYPE_VALUE(*cpp_type, buffer); - conversions.convert_to_uninitialized(CPPType::get<int>(), *cpp_type, &value, buffer); - return GVArray::ForSingle(*cpp_type, domain_num, buffer); - } - if (found_socket->type == SOCK_VECTOR) { - const float3 value = this->get_input<float3>(found_socket->identifier); - BUFFER_FOR_CPP_TYPE_VALUE(*cpp_type, buffer); - conversions.convert_to_uninitialized(CPPType::get<float3>(), *cpp_type, &value, buffer); - return GVArray::ForSingle(*cpp_type, domain_num, buffer); - } - if (found_socket->type == SOCK_RGBA) { - const ColorGeometry4f value = this->get_input<ColorGeometry4f>(found_socket->identifier); - BUFFER_FOR_CPP_TYPE_VALUE(*cpp_type, buffer); - conversions.convert_to_uninitialized( - CPPType::get<ColorGeometry4f>(), *cpp_type, &value, buffer); - return GVArray::ForSingle(*cpp_type, domain_num, buffer); - } - BLI_assert(false); - return GVArray::ForSingle(*cpp_type, domain_num, default_value); -} - -CustomDataType GeoNodeExecParams::get_input_attribute_data_type( - const StringRef name, - const GeometryComponent &component, - const CustomDataType default_type) const -{ - const bNodeSocket *found_socket = this->find_available_socket(name); - BLI_assert(found_socket != nullptr); /* There should always be available socket for the name. */ - if (found_socket == nullptr) { - return default_type; - } - - if (found_socket->type == SOCK_STRING) { - const std::string name = this->get_input<std::string>(found_socket->identifier); - std::optional<AttributeMetaData> info = component.attribute_get_meta_data(name); - if (info) { - return info->data_type; - } - return default_type; - } - if (found_socket->type == SOCK_FLOAT) { - return CD_PROP_FLOAT; - } - if (found_socket->type == SOCK_VECTOR) { - return CD_PROP_FLOAT3; - } - if (found_socket->type == SOCK_RGBA) { - return CD_PROP_COLOR; - } - if (found_socket->type == SOCK_BOOLEAN) { - return CD_PROP_BOOL; - } - - BLI_assert(false); - return default_type; -} - -AttributeDomain GeoNodeExecParams::get_highest_priority_input_domain( - Span<std::string> names, - const GeometryComponent &component, - const AttributeDomain default_domain) const -{ - Vector<AttributeDomain, 8> input_domains; - for (const std::string &name : names) { - const bNodeSocket *found_socket = this->find_available_socket(name); - BLI_assert(found_socket != nullptr); /* A socket should be available socket for the name. */ - if (found_socket == nullptr) { - continue; - } - - if (found_socket->type == SOCK_STRING) { - const std::string name = this->get_input<std::string>(found_socket->identifier); - std::optional<AttributeMetaData> info = component.attribute_get_meta_data(name); - if (info) { - input_domains.append(info->domain); - } - } - } - - if (input_domains.size() > 0) { - return bke::attribute_domain_highest_priority(input_domains); - } - - return default_domain; -} - std::string GeoNodeExecParams::attribute_producer_name() const { return provider_->dnode->label_or_name() + TIP_(" node"); diff --git a/source/blender/nodes/shader/nodes/node_shader_map_range.cc b/source/blender/nodes/shader/nodes/node_shader_map_range.cc index a487e07bd5a..5fc69987c67 100644 --- a/source/blender/nodes/shader/nodes/node_shader_map_range.cc +++ b/source/blender/nodes/shader/nodes/node_shader_map_range.cc @@ -53,7 +53,7 @@ static void node_shader_buts_map_range(uiLayout *layout, bContext *UNUSED(C), Po static int node_shader_map_range_ui_class(const bNode *node) { const NodeMapRange &storage = node_storage(*node); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); if (data_type == CD_PROP_FLOAT3) { return NODE_CLASS_OP_VECTOR; } @@ -63,7 +63,7 @@ static int node_shader_map_range_ui_class(const bNode *node) static void node_shader_update_map_range(bNodeTree *ntree, bNode *node) { const NodeMapRange &storage = node_storage(*node); - const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); + const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); const int type = (data_type == CD_PROP_FLOAT) ? SOCK_FLOAT : SOCK_VECTOR; Array<bool> new_input_availability(BLI_listbase_count(&node->inputs)); @@ -108,7 +108,7 @@ static void node_shader_init_map_range(bNodeTree *UNUSED(ntree), bNode *node) class SocketSearchOp { public: std::string socket_name; - CustomDataType data_type; + eCustomDataType data_type; int interpolation_type = NODE_MAP_RANGE_LINEAR; void operator()(LinkSearchOpParams ¶ms) @@ -120,7 +120,7 @@ class SocketSearchOp { } }; -static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSocket &socket) +static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket) { switch (socket.type) { case SOCK_FLOAT: @@ -137,7 +137,7 @@ static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSock static void node_map_range_gather_link_searches(GatherLinkSearchOpParams ¶ms) { - const std::optional<CustomDataType> type = node_type_from_other_socket(params.other_socket()); + const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket()); if (!type) { return; } diff --git a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc index 91d89952da7..53228f0a314 100644 --- a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc +++ b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc @@ -46,7 +46,7 @@ static int node_shader_gpu_uvmap(GPUMaterial *mat, NodeShaderUVMap *attr = static_cast<NodeShaderUVMap *>(node->storage); /* NOTE: using CD_AUTO_FROM_NAME instead of CD_MTFACE as geometry nodes may overwrite data which - * will also change the CustomDataType. This will also make EEVEE and Cycles consistent. See + * will also change the eCustomDataType. This will also make EEVEE and Cycles consistent. See * T93179. */ GPUNodeLink *mtface = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->uv_map); diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc index cba944c671c..830f02d8df1 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc @@ -43,7 +43,7 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat, { NodeShaderVertexColor *vertexColor = (NodeShaderVertexColor *)node->storage; /* NOTE: using CD_AUTO_FROM_NAME instead of CD_MCOL or CD_PROP_COLOR for named attributes - * as geometry nodes may overwrite data which will also change the CustomDataType. + * as geometry nodes may overwrite data which will also change the eCustomDataType. * This will also make EEVEE and Cycles * consistent. See T93179. */ diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index 621cc79a8db..939473ceaa0 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -36,15 +36,19 @@ #include "BKE_appdir.h" #include "BKE_blender_version.h" #include "BKE_global.h" +#include "BKE_main.h" #include "DNA_ID.h" #include "UI_interface_icons.h" +#include "RNA_enum_types.h" /* For `rna_enum_wm_job_type_items`. */ + /* for notifiers */ #include "WM_api.h" #include "WM_types.h" +#include "../generic/py_capi_rna.h" #include "../generic/py_capi_utils.h" #include "../generic/python_utildefines.h" @@ -450,6 +454,44 @@ static PyGetSetDef bpy_app_getsets[] = { {NULL, NULL, NULL, NULL, NULL}, }; +PyDoc_STRVAR(bpy_app_is_job_running_doc, + ".. staticmethod:: is_job_running(job_type)\n" + "\n" + " Check whether a job of the given type is running.\n" + "\n" + " :arg job_type: job type in :ref:`rna_enum_wm_job_type_items`.\n" + " :type job_type: str\n" + " :return: Whether a job of the given type is currently running.\n" + " :rtype: bool.\n"); +static PyObject *bpy_app_is_job_running(PyObject *UNUSED(self), PyObject *args, PyObject *kwds) +{ + struct BPy_EnumProperty_Parse job_type_enum = { + .items = rna_enum_wm_job_type_items, + .value = 0, + }; + static const char *_keywords[] = {"job_type", NULL}; + static _PyArg_Parser _parser = { + "O&" /* `job_type` */ + ":is_job_running", + _keywords, + 0, + }; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kwds, &_parser, pyrna_enum_value_parse_string, &job_type_enum)) { + return NULL; + } + wmWindowManager *wm = G_MAIN->wm.first; + return PyBool_FromLong(WM_jobs_has_running_type(wm, job_type_enum.value)); +} + +static struct PyMethodDef bpy_app_methods[] = { + {"is_job_running", + (PyCFunction)bpy_app_is_job_running, + METH_VARARGS | METH_KEYWORDS | METH_STATIC, + bpy_app_is_job_running_doc}, + {NULL, NULL, 0, NULL}, +}; + static void py_struct_seq_getset_init(void) { /* tricky dynamic members, not to py-spec! */ @@ -459,6 +501,17 @@ static void py_struct_seq_getset_init(void) Py_DECREF(item); } } + +static void py_struct_seq_method_init(void) +{ + for (PyMethodDef *method = bpy_app_methods; method->ml_name; method++) { + BLI_assert_msg(method->ml_flags & METH_STATIC, "Only static methods make sense for 'bpy.app'"); + PyObject *item = PyCFunction_New(method, NULL); + PyDict_SetItemString(BlenderAppType.tp_dict, method->ml_name, item); + Py_DECREF(item); + } +} + /* end dynamic bpy.app */ PyObject *BPY_app_struct(void) @@ -477,6 +530,7 @@ PyObject *BPY_app_struct(void) /* kindof a hack ontop of PyStructSequence */ py_struct_seq_getset_init(); + py_struct_seq_method_init(); return ret; } diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index bf427d9639a..641727927ec 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -66,6 +66,12 @@ static PyStructSequence_Field app_cb_info_fields[] = { {"xr_session_start_pre", "on starting an xr session (before)"}, {"annotation_pre", "on drawing an annotation (before)"}, {"annotation_post", "on drawing an annotation (after)"}, + {"object_bake_pre", "before starting a bake job"}, + {"object_bake_complete", "on completing a bake job; will be called in the main thread"}, + {"object_bake_cancel", "on canceling a bake job; will be called in the main thread"}, + {"composite_pre", "on a compositing background job (before)"}, + {"composite_post", "on a compositing background job (after)"}, + {"composite_cancel", "on a compositing background job (cancel)"}, /* sets the permanent tag */ #define APP_CB_OTHER_FIELDS 1 diff --git a/source/blender/python/rna_dump.py b/source/blender/python/rna_dump.py index 61df784336c..b4e23547c62 100644 --- a/source/blender/python/rna_dump.py +++ b/source/blender/python/rna_dump.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-or-later -# <pep8 compliant> - if 1: # Print once every 1000 GEN_PATH = True diff --git a/source/blender/render/RE_pipeline.h b/source/blender/render/RE_pipeline.h index 0a8668221ad..39820603c98 100644 --- a/source/blender/render/RE_pipeline.h +++ b/source/blender/render/RE_pipeline.h @@ -247,15 +247,15 @@ void RE_render_result_full_channel_name(char *fullname, const char *passname, const char *viewname, const char *chan_id, - const int channel); + int channel); struct ImBuf *RE_render_result_rect_to_ibuf(struct RenderResult *rr, const struct ImageFormatData *imf, const float dither, - const int view_id); + int view_id); void RE_render_result_rect_from_ibuf(struct RenderResult *rr, const struct ImBuf *ibuf, - const int view_id); + int view_id); struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name); float *RE_RenderLayerGetPass(struct RenderLayer *rl, const char *name, const char *viewname); diff --git a/source/blender/render/RE_texture_margin.h b/source/blender/render/RE_texture_margin.h index 0c91abeaddd..023615cea87 100644 --- a/source/blender/render/RE_texture_margin.h +++ b/source/blender/render/RE_texture_margin.h @@ -27,16 +27,13 @@ struct Mesh; */ void RE_generate_texturemargin_adjacentfaces(struct ImBuf *ibuf, char *mask, - const int margin, + int margin, struct Mesh const *me, char const *uv_layer, const float uv_offset[2]); -void RE_generate_texturemargin_adjacentfaces_dm(struct ImBuf *ibuf, - char *mask, - const int margin, - struct DerivedMesh *dm, - const float uv_offset[2]); +void RE_generate_texturemargin_adjacentfaces_dm( + struct ImBuf *ibuf, char *mask, int margin, struct DerivedMesh *dm, const float uv_offset[2]); #ifdef __cplusplus } diff --git a/source/blender/render/intern/render_result.h b/source/blender/render/intern/render_result.h index 30f49775562..c84e0a04018 100644 --- a/source/blender/render/intern/render_result.h +++ b/source/blender/render/intern/render_result.h @@ -44,7 +44,7 @@ struct RenderResult *render_result_new(struct Render *re, void render_result_passes_allocated_ensure(struct RenderResult *rr); /** - * From imbuf, if a handle was returned and + * From `imbuf`, if a handle was returned and * it's not a single-layer multi-view we convert this to render result. */ struct RenderResult *render_result_new_from_exr( diff --git a/source/blender/sequencer/SEQ_add.h b/source/blender/sequencer/SEQ_add.h index c195165a792..dea5151598c 100644 --- a/source/blender/sequencer/SEQ_add.h +++ b/source/blender/sequencer/SEQ_add.h @@ -183,9 +183,6 @@ void SEQ_add_image_load_file(struct Sequence *seq, size_t strip_frame, char *fil * \param seq: image strip to be changed */ void SEQ_add_image_init_alpha_mode(struct Sequence *seq); -/** - * \note caller should run `SEQ_time_update_sequence(scene, seq)` after.. - */ void SEQ_add_reload_new_file(struct Main *bmain, struct Scene *scene, struct Sequence *seq, diff --git a/source/blender/sequencer/SEQ_channels.h b/source/blender/sequencer/SEQ_channels.h index dcfdb933940..197ad5e55de 100644 --- a/source/blender/sequencer/SEQ_channels.h +++ b/source/blender/sequencer/SEQ_channels.h @@ -24,8 +24,8 @@ void SEQ_channels_duplicate(struct ListBase *channels_dst, struct ListBase *chan void SEQ_channels_free(struct ListBase *channels); struct SeqTimelineChannel *SEQ_channel_get_by_index(const struct ListBase *channels, - const int channel_index); -char *SEQ_channel_name_get(struct ListBase *channels, const int channel_index); + int channel_index); +char *SEQ_channel_name_get(struct ListBase *channels, int channel_index); bool SEQ_channel_is_locked(const struct SeqTimelineChannel *channel); bool SEQ_channel_is_muted(const struct SeqTimelineChannel *channel); int SEQ_channel_index_get(const struct SeqTimelineChannel *channel); diff --git a/source/blender/sequencer/SEQ_iterator.h b/source/blender/sequencer/SEQ_iterator.h index 8cb20d41ba2..1f94574513c 100644 --- a/source/blender/sequencer/SEQ_iterator.h +++ b/source/blender/sequencer/SEQ_iterator.h @@ -131,6 +131,9 @@ bool SEQ_collection_remove_strip(struct Sequence *seq, SeqCollection *collection * \param collection: collection to be freed */ void SEQ_collection_free(SeqCollection *collection); +/** Quiet compiler warning for free function. */ +#define SEQ_collection_free_void_p ((GHashValFreeFP)SEQ_collection_free) + /** * Move strips from collection_src to collection_dst. Source collection will be freed. * diff --git a/source/blender/sequencer/SEQ_sequencer.h b/source/blender/sequencer/SEQ_sequencer.h index 8ded6d99a8d..70cba58007f 100644 --- a/source/blender/sequencer/SEQ_sequencer.h +++ b/source/blender/sequencer/SEQ_sequencer.h @@ -143,7 +143,8 @@ typedef enum eSequenceLookupTag { * * \return pointer to Sequence */ -struct Sequence *SEQ_sequence_lookup_by_name(const struct Scene *scene, const char *key); +struct Sequence *SEQ_sequence_lookup_seq_by_name(const struct Scene *scene, const char *key); + /** * Free lookup hash data. * diff --git a/source/blender/sequencer/SEQ_time.h b/source/blender/sequencer/SEQ_time.h index 1da6efb1d04..eab10f2e852 100644 --- a/source/blender/sequencer/SEQ_time.h +++ b/source/blender/sequencer/SEQ_time.h @@ -47,8 +47,6 @@ int SEQ_time_find_next_prev_edit(struct Scene *scene, bool do_skip_mute, bool do_center, bool do_unselected); -void SEQ_time_update_sequence(struct Scene *scene, struct ListBase *seqbase, struct Sequence *seq); -void SEQ_time_update_recursive(struct Scene *scene, struct Sequence *changed_seq); /** * Test if strip intersects with timeline frame. * \note This checks if strip would be rendered at this frame. For rendering it is assumed, that @@ -59,14 +57,15 @@ void SEQ_time_update_recursive(struct Scene *scene, struct Sequence *changed_seq * \return true if strip intersects with timeline frame. */ bool SEQ_time_strip_intersects_frame(const struct Sequence *seq, int timeline_frame); -void SEQ_time_update_meta_strip_range(struct Scene *scene, struct Sequence *seq_meta); bool SEQ_time_has_still_frames(const struct Sequence *seq); bool SEQ_time_has_left_still_frames(const struct Sequence *seq); bool SEQ_time_has_right_still_frames(const struct Sequence *seq); -int SEQ_time_left_handle_frame_get(struct Sequence *seq); -int SEQ_time_right_handle_frame_get(struct Sequence *seq); -void SEQ_time_left_handle_frame_set(struct Sequence *seq, int val); -void SEQ_time_right_handle_frame_set(struct Sequence *seq, int val); + +int SEQ_time_left_handle_frame_get(const struct Sequence *seq); +int SEQ_time_right_handle_frame_get(const struct Sequence *seq); +void SEQ_time_left_handle_frame_set(const struct Scene *scene, struct Sequence *seq, int val); +void SEQ_time_right_handle_frame_set(const struct Scene *scene, struct Sequence *seq, int val); +void SEQ_time_update_meta_strip_range(const struct Scene *scene, struct Sequence *seq_meta); #ifdef __cplusplus } diff --git a/source/blender/sequencer/SEQ_transform.h b/source/blender/sequencer/SEQ_transform.h index bd4258bfdb1..93ce6873d3b 100644 --- a/source/blender/sequencer/SEQ_transform.h +++ b/source/blender/sequencer/SEQ_transform.h @@ -21,14 +21,17 @@ struct Sequence; * Use to impose limits when dragging/extending - so impossible situations don't happen. * Can't use the #SEQ_LEFTSEL and #SEQ_LEFTSEL directly because the strip may be in a meta-strip. */ -void SEQ_transform_handle_xlimits(struct Sequence *seq, int leftflag, int rightflag); +void SEQ_transform_handle_xlimits(const struct Scene *scene, + struct Sequence *seq, + int leftflag, + int rightflag); bool SEQ_transform_sequence_can_be_translated(struct Sequence *seq); /** * Used so we can do a quick check for single image seq * since they work a bit differently to normal image seq's (during transform). */ bool SEQ_transform_single_image_check(struct Sequence *seq); -void SEQ_transform_fix_single_image_seq_offsets(struct Sequence *seq); +void SEQ_transform_fix_single_image_seq_offsets(const struct Scene *scene, struct Sequence *seq); bool SEQ_transform_test_overlap(struct ListBase *seqbasep, struct Sequence *test); bool SEQ_transform_test_overlap_seq_seq(struct Sequence *seq1, struct Sequence *seq2); void SEQ_transform_translate_sequence(struct Scene *scene, struct Sequence *seq, int delta); diff --git a/source/blender/sequencer/SEQ_utils.h b/source/blender/sequencer/SEQ_utils.h index ce3c81606ea..24ca7559166 100644 --- a/source/blender/sequencer/SEQ_utils.h +++ b/source/blender/sequencer/SEQ_utils.h @@ -20,14 +20,6 @@ struct SeqRenderData; struct Sequence; struct StripElem; -/** - * Sort strips in provided seqbase. Effect strips are trailing the list and they are sorted by - * channel position as well. - * This is important for SEQ_time_update_sequence to work properly - * - * \param seqbase: ListBase with strips - */ -void SEQ_sort(struct ListBase *seqbase); void SEQ_sequence_base_unique_name_recursive(struct Scene *scene, struct ListBase *seqbasep, struct Sequence *seq); @@ -39,7 +31,7 @@ const struct Sequence *SEQ_get_topmost_sequence(const struct Scene *scene, int f /** * In cases where we don't know the sequence's listbase. */ -struct ListBase *SEQ_get_seqbase_by_seq(struct ListBase *seqbase, struct Sequence *seq); +struct ListBase *SEQ_get_seqbase_by_seq(const struct Scene *scene, struct Sequence *seq); /** * Only use as last resort when the StripElem is available but no the Sequence. * (needed for RNA) diff --git a/source/blender/sequencer/intern/disk_cache.c b/source/blender/sequencer/intern/disk_cache.c index f8e8fc32a5d..cc34066c432 100644 --- a/source/blender/sequencer/intern/disk_cache.c +++ b/source/blender/sequencer/intern/disk_cache.c @@ -37,6 +37,7 @@ #include "SEQ_relations.h" #include "SEQ_render.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" #include "disk_cache.h" #include "image_cache.h" @@ -411,8 +412,8 @@ void seq_disk_cache_invalidate(SeqDiskCache *disk_cache, BLI_mutex_lock(&disk_cache->read_write_mutex); - start = seq_changed->startdisp - DCACHE_IMAGES_PER_FILE; - end = seq_changed->enddisp; + start = SEQ_time_left_handle_frame_get(seq_changed) - DCACHE_IMAGES_PER_FILE; + end = SEQ_time_right_handle_frame_get(seq_changed); seq_disk_cache_delete_invalid_files(disk_cache, scene, seq, invalidate_types, start, end); diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index d9d21ee3b05..0e5e56908b0 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -49,6 +49,7 @@ #include "SEQ_proxy.h" #include "SEQ_relations.h" #include "SEQ_render.h" +#include "SEQ_time.h" #include "SEQ_utils.h" #include "BLF_api.h" @@ -2431,7 +2432,7 @@ static ImBuf *do_multicam(const SeqRenderData *context, if (!ed) { return NULL; } - ListBase *seqbasep = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); + ListBase *seqbasep = SEQ_get_seqbase_by_seq(context->scene, seq); ListBase *channels = SEQ_get_channels_by_seq(&ed->seqbase, &ed->channels, seq); if (!seqbasep) { return NULL; @@ -2467,13 +2468,15 @@ static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, fl ed = context->scene->ed; - ListBase *seqbasep = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); + ListBase *seqbasep = SEQ_get_seqbase_by_seq(context->scene, seq); ListBase *channels = SEQ_get_channels_by_seq(&ed->seqbase, &ed->channels, seq); /* Clamp timeline_frame to strip range so it behaves as if it had "still frame" offset (last * frame is static after end of strip). This is how most strips behave. This way transition * effects that doesn't overlap or speed effect can't fail rendering outside of strip range. */ - timeline_frame = clamp_i(timeline_frame, seq->startdisp, seq->enddisp - 1); + timeline_frame = clamp_i(timeline_frame, + SEQ_time_left_handle_frame_get(seq), + SEQ_time_right_handle_frame_get(seq) - 1); if (seq->machine > 1) { i = seq_render_give_ibuf_seqbase( @@ -2583,7 +2586,7 @@ static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(fac)) static int seq_effect_speed_get_strip_content_length(const Sequence *seq) { if ((seq->type & SEQ_TYPE_EFFECT) != 0 && SEQ_effect_get_num_inputs(seq->type) == 0) { - return seq->enddisp - seq->startdisp; + return SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq); } return seq->len; @@ -2610,13 +2613,14 @@ void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq) MEM_freeN(v->frameMap); } - const int effect_strip_length = seq->enddisp - seq->startdisp; + const int effect_strip_length = SEQ_time_right_handle_frame_get(seq) - + SEQ_time_left_handle_frame_get(seq); v->frameMap = MEM_mallocN(sizeof(float) * effect_strip_length, __func__); v->frameMap[0] = 0.0f; float target_frame = 0; for (int frame_index = 1; frame_index < effect_strip_length; frame_index++) { - target_frame += evaluate_fcurve(fcu, seq->startdisp + frame_index); + target_frame += evaluate_fcurve(fcu, SEQ_time_left_handle_frame_get(seq) + frame_index); CLAMP(target_frame, 0, seq->seq1->len); v->frameMap[frame_index] = target_frame; } @@ -2652,7 +2656,8 @@ float seq_speed_effect_target_frame_get(Scene *scene, /* Only right handle controls effect speed! */ const float target_content_length = seq_effect_speed_get_strip_content_length(source) - source->startofs; - const float speed_effetct_length = seq_speed->enddisp - seq_speed->startdisp; + const float speed_effetct_length = SEQ_time_right_handle_frame_get(seq_speed) - + SEQ_time_left_handle_frame_get(seq_speed); const float ratio = frame_index / speed_effetct_length; target_frame = target_content_length * ratio; break; @@ -3509,7 +3514,7 @@ static void get_default_fac_noop(Sequence *UNUSED(seq), float UNUSED(timeline_fr static void get_default_fac_fade(Sequence *seq, float timeline_frame, float *fac) { - *fac = (float)(timeline_frame - seq->startdisp); + *fac = (float)(timeline_frame - SEQ_time_left_handle_frame_get(seq)); *fac /= seq->len; } diff --git a/source/blender/sequencer/intern/image_cache.c b/source/blender/sequencer/intern/image_cache.c index e1ff0ff64b3..59de24930d6 100644 --- a/source/blender/sequencer/intern/image_cache.c +++ b/source/blender/sequencer/intern/image_cache.c @@ -36,6 +36,7 @@ #include "SEQ_prefetch.h" #include "SEQ_relations.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" #include "disk_cache.h" #include "image_cache.h" @@ -558,8 +559,9 @@ void seq_cache_free_temp_cache(Scene *scene, short id, int timeline_frame) /* Use frame_index here to avoid freeing raw images if they are used for multiple frames. */ float frame_index = seq_cache_timeline_frame_to_frame_index( key->seq, timeline_frame, key->type); - if (frame_index != key->frame_index || timeline_frame > key->seq->enddisp || - timeline_frame < key->seq->startdisp) { + if (frame_index != key->frame_index || + timeline_frame > SEQ_time_right_handle_frame_get(key->seq) || + timeline_frame < SEQ_time_left_handle_frame_get(key->seq)) { BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree); } } @@ -634,8 +636,8 @@ void seq_cache_cleanup_sequence(Scene *scene, seq_cache_lock(scene); - int range_start = seq_changed->startdisp; - int range_end = seq_changed->enddisp; + int range_start = SEQ_time_left_handle_frame_get(seq_changed); + int range_end = SEQ_time_right_handle_frame_get(seq_changed); if (!force_seq_changed_range) { if (seq->startdisp > range_start) { @@ -668,8 +670,8 @@ void seq_cache_cleanup_sequence(Scene *scene, } if (key->type & invalidate_source && key->seq == seq && - key->timeline_frame >= seq_changed->startdisp && - key->timeline_frame <= seq_changed->enddisp) { + key->timeline_frame >= SEQ_time_left_handle_frame_get(seq_changed) && + key->timeline_frame <= SEQ_time_right_handle_frame_get(seq_changed)) { if (key->link_next || key->link_prev) { seq_cache_relink_keys(key->link_next, key->link_prev); } @@ -700,11 +702,12 @@ void seq_cache_thumbnail_cleanup(Scene *scene, rctf *view_area_safe) SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter); BLI_ghashIterator_step(&gh_iter); - const int frame_index = key->timeline_frame - key->seq->startdisp; + const int frame_index = key->timeline_frame - SEQ_time_left_handle_frame_get(key->seq); const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(key->seq); const int relative_base_frame = round_fl_to_int((frame_index / (float)frame_step)) * frame_step; - const int nearest_guaranted_absolute_frame = relative_base_frame + key->seq->startdisp; + const int nearest_guaranted_absolute_frame = relative_base_frame + + SEQ_time_left_handle_frame_get(key->seq); if (nearest_guaranted_absolute_frame == key->timeline_frame) { continue; diff --git a/source/blender/sequencer/intern/proxy.c b/source/blender/sequencer/intern/proxy.c index 59b4c6de1ef..464580f5bed 100644 --- a/source/blender/sequencer/intern/proxy.c +++ b/source/blender/sequencer/intern/proxy.c @@ -43,6 +43,7 @@ #include "SEQ_relations.h" #include "SEQ_render.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" #include "multiview.h" #include "proxy.h" @@ -523,7 +524,9 @@ void SEQ_proxy_rebuild(SeqIndexBuildContext *context, SeqRenderState state; seq_render_state_init(&state); - for (timeline_frame = seq->startdisp; timeline_frame < seq->enddisp; timeline_frame++) { + for (timeline_frame = SEQ_time_left_handle_frame_get(seq); + timeline_frame < SEQ_time_right_handle_frame_get(seq); + timeline_frame++) { if (context->size_flags & IMB_PROXY_25) { seq_proxy_build_frame(&render_context, &state, seq, timeline_frame, 25, overwrite); } @@ -537,7 +540,8 @@ void SEQ_proxy_rebuild(SeqIndexBuildContext *context, seq_proxy_build_frame(&render_context, &state, seq, timeline_frame, 100, overwrite); } - *progress = (float)(timeline_frame - seq->startdisp) / (seq->enddisp - seq->startdisp); + *progress = (float)(timeline_frame - SEQ_time_left_handle_frame_get(seq)) / + (SEQ_time_right_handle_frame_get(seq) - SEQ_time_left_handle_frame_get(seq)); *do_update = true; if (*stop || G.is_break) { diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index b0898be3765..e7a1bbeb9d0 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -1994,11 +1994,12 @@ ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context, float SEQ_render_thumbnail_first_frame_get(Sequence *seq, float frame_step, rctf *view_area) { - int first_drawable_frame = max_iii(seq->startdisp, seq->start, view_area->xmin); + int first_drawable_frame = max_iii( + SEQ_time_left_handle_frame_get(seq), seq->start, view_area->xmin); /* First frame should correspond to handle position. */ - if (first_drawable_frame == seq->startdisp) { - return seq->startdisp; + if (first_drawable_frame == SEQ_time_left_handle_frame_get(seq)) { + return SEQ_time_left_handle_frame_get(seq); } float aligned_frame_offset = (int)((first_drawable_frame - seq->start) / frame_step) * @@ -2011,7 +2012,7 @@ float SEQ_render_thumbnail_next_frame_get(Sequence *seq, float last_frame, float float next_frame = last_frame + frame_step; /* If handle position was displayed, align next frame with `seq->start`. */ - if (last_frame == seq->startdisp) { + if (last_frame == SEQ_time_left_handle_frame_get(seq)) { next_frame = seq->start + ((int)((last_frame - seq->start) / frame_step) + 1) * frame_step; } @@ -2088,8 +2089,9 @@ void SEQ_render_thumbnails(const SeqRenderData *context, /* Adding the hold offset value (seq->anim_startofs) to the start frame. Position of image not * affected, but frame loaded affected. */ - float upper_thumb_bound = SEQ_time_has_right_still_frames(seq) ? (seq->start + seq->len) : - seq->enddisp; + float upper_thumb_bound = SEQ_time_has_right_still_frames(seq) ? + (seq->start + seq->len) : + SEQ_time_right_handle_frame_get(seq); upper_thumb_bound = (upper_thumb_bound > view_area->xmax) ? view_area->xmax + frame_step : upper_thumb_bound; @@ -2122,8 +2124,8 @@ void SEQ_render_thumbnails(const SeqRenderData *context, int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Sequence *seq) { - const int content_start = max_ii(seq->startdisp, seq->start); - const int content_end = min_ii(seq->enddisp, seq->start + seq->len); + const int content_start = max_ii(SEQ_time_left_handle_frame_get(seq), seq->start); + const int content_end = min_ii(SEQ_time_right_handle_frame_get(seq), seq->start + seq->len); const int content_len = content_end - content_start; /* Arbitrary, but due to performance reasons should be as low as possible. */ @@ -2143,10 +2145,10 @@ void SEQ_render_thumbnails_base_set(const SeqRenderData *context, SeqRenderState state; seq_render_state_init(&state); - int timeline_frame = seq->startdisp; + int timeline_frame = SEQ_time_left_handle_frame_get(seq); const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(seq); - while (timeline_frame < seq->enddisp && !*stop) { + while (timeline_frame < SEQ_time_right_handle_frame_get(seq) && !*stop) { ImBuf *ibuf = seq_cache_get( context, seq_orig, roundf(timeline_frame), SEQ_CACHE_STORE_THUMBNAIL); if (ibuf) { diff --git a/source/blender/sequencer/intern/sequence_lookup.c b/source/blender/sequencer/intern/sequence_lookup.c index 2a2626d8abf..8d18e381171 100644 --- a/source/blender/sequencer/intern/sequence_lookup.c +++ b/source/blender/sequencer/intern/sequence_lookup.c @@ -6,6 +6,7 @@ */ #include "SEQ_sequencer.h" +#include "sequencer.h" #include "DNA_listBase.h" #include "DNA_scene_types.h" @@ -14,6 +15,7 @@ #include "SEQ_iterator.h" #include "BLI_ghash.h" +#include "BLI_listbase.h" #include "BLI_string.h" #include "BLI_sys_types.h" #include "BLI_threads.h" @@ -24,24 +26,66 @@ static ThreadMutex lookup_lock = BLI_MUTEX_INITIALIZER; typedef struct SequenceLookup { - GHash *by_name; + GHash *seq_by_name; + GHash *meta_by_seq; + GHash *effects_by_seq; eSequenceLookupTag tag; } SequenceLookup; static void seq_sequence_lookup_init(struct SequenceLookup *lookup) { - lookup->by_name = BLI_ghash_str_new(__func__); + lookup->seq_by_name = BLI_ghash_str_new(__func__); + lookup->meta_by_seq = BLI_ghash_ptr_new(__func__); + lookup->effects_by_seq = BLI_ghash_ptr_new(__func__); lookup->tag |= SEQ_LOOKUP_TAG_INVALID; } -static void seq_sequence_lookup_build(const struct Scene *scene, struct SequenceLookup *lookup) +static void seq_sequence_lookup_append_effect(Sequence *input, + Sequence *effect, + struct SequenceLookup *lookup) +{ + if (input == NULL) { + return; + } + + SeqCollection *effects = BLI_ghash_lookup(lookup->effects_by_seq, input); + if (effects == NULL) { + effects = SEQ_collection_create(__func__); + BLI_ghash_insert(lookup->effects_by_seq, input, effects); + } + + SEQ_collection_append_strip(effect, effects); +} + +static void seq_sequence_lookup_build_effect(Sequence *seq, struct SequenceLookup *lookup) { - SeqCollection *all_strips = SEQ_query_all_strips_recursive(&scene->ed->seqbase); - Sequence *seq; - SEQ_ITERATOR_FOREACH (seq, all_strips) { - BLI_ghash_insert(lookup->by_name, seq->name + 2, seq); + if ((seq->type & SEQ_TYPE_EFFECT) == 0) { + return; } - SEQ_collection_free(all_strips); + + seq_sequence_lookup_append_effect(seq->seq1, seq, lookup); + seq_sequence_lookup_append_effect(seq->seq2, seq, lookup); +} + +static void seq_sequence_lookup_build_from_seqbase(Sequence *parent_meta, + const ListBase *seqbase, + struct SequenceLookup *lookup) +{ + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + BLI_ghash_insert(lookup->seq_by_name, seq->name + 2, seq); + BLI_ghash_insert(lookup->meta_by_seq, seq, parent_meta); + seq_sequence_lookup_build_effect(seq, lookup); + + if (seq->type == SEQ_TYPE_META) { + seq_sequence_lookup_build_from_seqbase(seq, &seq->seqbase, lookup); + } + } +} + +static void seq_sequence_lookup_build(const struct Scene *scene, struct SequenceLookup *lookup) +{ + Editing *ed = SEQ_editing_get(scene); + seq_sequence_lookup_build_from_seqbase(NULL, &ed->seqbase, lookup); lookup->tag &= ~SEQ_LOOKUP_TAG_INVALID; } @@ -58,8 +102,12 @@ static void seq_sequence_lookup_free(struct SequenceLookup **lookup) return; } - BLI_ghash_free((*lookup)->by_name, NULL, NULL); - (*lookup)->by_name = NULL; + BLI_ghash_free((*lookup)->seq_by_name, NULL, NULL); + BLI_ghash_free((*lookup)->meta_by_seq, NULL, NULL); + BLI_ghash_free((*lookup)->effects_by_seq, NULL, SEQ_collection_free_void_p); + (*lookup)->seq_by_name = NULL; + (*lookup)->meta_by_seq = NULL; + (*lookup)->effects_by_seq = NULL; MEM_freeN(*lookup); *lookup = NULL; } @@ -98,17 +146,39 @@ void SEQ_sequence_lookup_free(const Scene *scene) BLI_mutex_unlock(&lookup_lock); } -Sequence *SEQ_sequence_lookup_by_name(const Scene *scene, const char *key) +Sequence *SEQ_sequence_lookup_seq_by_name(const Scene *scene, const char *key) +{ + BLI_assert(scene->ed); + BLI_mutex_lock(&lookup_lock); + seq_sequence_lookup_update_if_needed(scene, &scene->ed->runtime.sequence_lookup); + SequenceLookup *lookup = scene->ed->runtime.sequence_lookup; + Sequence *seq = BLI_ghash_lookup(lookup->seq_by_name, key); + BLI_mutex_unlock(&lookup_lock); + return seq; +} + +Sequence *seq_sequence_lookup_meta_by_seq(const Scene *scene, const Sequence *key) { BLI_assert(scene->ed); BLI_mutex_lock(&lookup_lock); seq_sequence_lookup_update_if_needed(scene, &scene->ed->runtime.sequence_lookup); SequenceLookup *lookup = scene->ed->runtime.sequence_lookup; - Sequence *seq = BLI_ghash_lookup(lookup->by_name, key); + Sequence *seq = BLI_ghash_lookup(lookup->meta_by_seq, key); BLI_mutex_unlock(&lookup_lock); return seq; } +SeqCollection *seq_sequence_lookup_effects_by_seq(const Scene *scene, const Sequence *key) +{ + BLI_assert(scene->ed); + BLI_mutex_lock(&lookup_lock); + seq_sequence_lookup_update_if_needed(scene, &scene->ed->runtime.sequence_lookup); + SequenceLookup *lookup = scene->ed->runtime.sequence_lookup; + SeqCollection *effects = BLI_ghash_lookup(lookup->effects_by_seq, key); + BLI_mutex_unlock(&lookup_lock); + return effects; +} + void SEQ_sequence_lookup_tag(const Scene *scene, eSequenceLookupTag tag) { if (!scene->ed) { diff --git a/source/blender/sequencer/intern/sequencer.h b/source/blender/sequencer/intern/sequencer.h index 9f5bdf672c0..5e78c8c6f96 100644 --- a/source/blender/sequencer/intern/sequencer.h +++ b/source/blender/sequencer/intern/sequencer.h @@ -14,13 +14,37 @@ extern "C" { struct Scene; struct Sequence; struct StripProxy; +struct SeqCollection; /** * Cache must be freed before calling this function * since it leaves the seqbase in an invalid state. */ void seq_free_sequence_recurse(struct Scene *scene, struct Sequence *seq, bool do_id_user); struct StripProxy *seq_strip_proxy_alloc(void); - +/** + * Find meta strip, that contains strip `key`. + * If lookup hash doesn't exist, it will be created. If hash is tagged as invalid, it will be + * rebuilt. + * + * \param scene: scene that owns lookup hash + * \param key: pointer to Sequence inside of meta strip + * + * \return pointer to meta strip + */ +struct Sequence *seq_sequence_lookup_meta_by_seq(const struct Scene *scene, + const struct Sequence *key); +/** + * Find effect strips, that use strip `seq` as one of inputs. + * If lookup hash doesn't exist, it will be created. If hash is tagged as invalid, it will be + * rebuilt. + * + * \param scene: scene that owns lookup hash + * \param key: pointer to Sequence inside of meta strip + * + * \return collection of effect strips + */ +struct SeqCollection *seq_sequence_lookup_effects_by_seq(const struct Scene *scene, + const struct Sequence *key); #ifdef __cplusplus } #endif diff --git a/source/blender/sequencer/intern/sound.c b/source/blender/sequencer/intern/sound.c index 8076c600560..50c8b76a9a0 100644 --- a/source/blender/sequencer/intern/sound.c +++ b/source/blender/sequencer/intern/sound.c @@ -35,7 +35,6 @@ static bool sequencer_refresh_sound_length_recursive(Main *bmain, Scene *scene, for (seq = seqbase->first; seq; seq = seq->next) { if (seq->type == SEQ_TYPE_META) { if (sequencer_refresh_sound_length_recursive(bmain, scene, &seq->seqbase)) { - SEQ_time_update_sequence(scene, seqbase, seq); changed = true; } } @@ -55,7 +54,6 @@ static bool sequencer_refresh_sound_length_recursive(Main *bmain, Scene *scene, seq->endofs *= fac; seq->start += (old - seq->startofs); /* So that visual/"real" start frame does not change! */ - SEQ_time_update_sequence(scene, seqbase, seq); changed = true; } } @@ -99,8 +97,12 @@ void SEQ_sound_update_bounds(Scene *scene, Sequence *seq) /* We have to take into account start frame of the sequence's scene! */ int startofs = seq->startofs + seq->anim_startofs + seq->scene->r.sfra; - BKE_sound_move_scene_sound( - scene, seq->scene_sound, seq->startdisp, seq->enddisp, startofs, 0.0); + BKE_sound_move_scene_sound(scene, + seq->scene_sound, + SEQ_time_left_handle_frame_get(seq), + SEQ_time_right_handle_frame_get(seq), + startofs, + 0.0); } } else { diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c index 77b0fc946d9..4f0b2e38f56 100644 --- a/source/blender/sequencer/intern/strip_add.c +++ b/source/blender/sequencer/intern/strip_add.c @@ -51,6 +51,8 @@ #include "multiview.h" #include "proxy.h" +#include "sequencer.h" +#include "strip_time.h" #include "utils.h" void SEQ_add_load_data_init(SeqLoadData *load_data, @@ -70,12 +72,12 @@ void SEQ_add_load_data_init(SeqLoadData *load_data, load_data->channel = channel; } -static void seq_add_generic_update(Scene *scene, ListBase *seqbase, Sequence *seq) +static void seq_add_generic_update(Scene *scene, Sequence *seq) { SEQ_sequence_base_unique_name_recursive(scene, &scene->ed->seqbase, seq); - SEQ_time_update_sequence(scene, seqbase, seq); - SEQ_sort(seqbase); SEQ_relations_invalidate_cache_composite(scene, seq); + SEQ_sequence_lookup_tag(scene, SEQ_LOOKUP_TAG_INVALID); + SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq)); } static void seq_add_set_name(Scene *scene, Sequence *seq, SeqLoadData *load_data) @@ -128,7 +130,7 @@ Sequence *SEQ_add_scene_strip(Scene *scene, ListBase *seqbase, struct SeqLoadDat seq->len = load_data->scene->r.efra - load_data->scene->r.sfra + 1; id_us_ensure_real((ID *)load_data->scene); seq_add_set_name(scene, seq, load_data); - seq_add_generic_update(scene, seqbase, seq); + seq_add_generic_update(scene, seq); return seq; } @@ -140,7 +142,7 @@ Sequence *SEQ_add_movieclip_strip(Scene *scene, ListBase *seqbase, struct SeqLoa seq->len = BKE_movieclip_get_duration(load_data->clip); id_us_ensure_real((ID *)load_data->clip); seq_add_set_name(scene, seq, load_data); - seq_add_generic_update(scene, seqbase, seq); + seq_add_generic_update(scene, seq); return seq; } @@ -152,7 +154,7 @@ Sequence *SEQ_add_mask_strip(Scene *scene, ListBase *seqbase, struct SeqLoadData seq->len = BKE_mask_get_duration(load_data->mask); id_us_ensure_real((ID *)load_data->mask); seq_add_set_name(scene, seq, load_data); - seq_add_generic_update(scene, seqbase, seq); + seq_add_generic_update(scene, seq); return seq; } @@ -174,11 +176,12 @@ Sequence *SEQ_add_effect_strip(Scene *scene, ListBase *seqbase, struct SeqLoadDa if (!load_data->effect.seq1) { seq->len = 1; /* Effect is generator, set non zero length. */ - SEQ_time_right_handle_frame_set(seq, load_data->effect.end_frame); + SEQ_time_right_handle_frame_set(scene, seq, load_data->effect.end_frame); } seq_add_set_name(scene, seq, load_data); - seq_add_generic_update(scene, seqbase, seq); + seq_add_generic_update(scene, seq); + seq_time_effect_range_set(seq); return seq; } @@ -264,7 +267,7 @@ Sequence *SEQ_add_image_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL BLI_strncpy(scene->ed->act_imagedir, seq->strip->dir, sizeof(scene->ed->act_imagedir)); seq_add_set_view_transform(scene, seq, load_data); seq_add_set_name(scene, seq, load_data); - seq_add_generic_update(scene, seqbase, seq); + seq_add_generic_update(scene, seq); return seq; } @@ -335,7 +338,7 @@ Sequence *SEQ_add_sound_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL /* Set Last active directory. */ BLI_strncpy(scene->ed->act_sounddir, strip->dir, FILE_MAXDIR); seq_add_set_name(scene, seq, load_data); - seq_add_generic_update(scene, seqbase, seq); + seq_add_generic_update(scene, seq); return seq; } @@ -362,7 +365,6 @@ Sequence *SEQ_add_meta_strip(Scene *scene, ListBase *seqbase, SeqLoadData *load_ /* Set frames start and length. */ seqm->start = load_data->start_frame; seqm->len = 1; - SEQ_time_update_sequence(scene, seqbase, seqm); return seqm; } @@ -484,7 +486,7 @@ Sequence *SEQ_add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL seq_add_set_view_transform(scene, seq, load_data); seq_add_set_name(scene, seq, load_data); - seq_add_generic_update(scene, seqbase, seq); + seq_add_generic_update(scene, seq); MEM_freeN(anim_arr); return seq; @@ -509,11 +511,8 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo if (lock_range) { /* keep so we don't have to move the actual start and end points (only the data) */ - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); - SEQ_time_update_sequence(scene, seqbase, seq); - prev_startdisp = seq->startdisp; - prev_enddisp = seq->enddisp; + prev_startdisp = SEQ_time_left_handle_frame_get(seq); + prev_enddisp = SEQ_time_right_handle_frame_get(seq); } switch (seq->type) { @@ -656,13 +655,11 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo free_proxy_seq(seq); if (lock_range) { - SEQ_time_left_handle_frame_set(seq, prev_startdisp); - SEQ_time_right_handle_frame_set(seq, prev_enddisp); - SEQ_transform_fix_single_image_seq_offsets(seq); + SEQ_time_left_handle_frame_set(scene, seq, prev_startdisp); + SEQ_time_right_handle_frame_set(scene, seq, prev_enddisp); + SEQ_transform_fix_single_image_seq_offsets(scene, seq); } - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); - SEQ_time_update_sequence(scene, seqbase, seq); SEQ_relations_invalidate_cache_raw(scene, seq); } diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index 96bfce8f740..bd439e3c9f8 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -84,8 +84,8 @@ int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_ SWAP(int, seq_a->startofs, seq_b->startofs); SWAP(int, seq_a->endofs, seq_b->endofs); SWAP(int, seq_a->machine, seq_b->machine); - SWAP(int, seq_a->startdisp, seq_b->startdisp); - SWAP(int, seq_a->enddisp, seq_b->enddisp); + seq_time_effect_range_set(seq_a); + seq_time_effect_range_set(seq_b); return 1; } @@ -230,7 +230,7 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene, { /* Find the appropriate seqbase */ Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, src_seq); + ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, src_seq); if (dst_seqm->type != SEQ_TYPE_META) { *error_str = N_("Can not move strip to non-meta strip"); @@ -272,11 +272,11 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene, return true; } -static void seq_split_set_left_hold_offset(Sequence *seq, int timeline_frame) +static void seq_split_set_left_hold_offset(const Scene *scene, Sequence *seq, int timeline_frame) { /* Adjust within range of extended stillframes before strip. */ if (timeline_frame < seq->start) { - SEQ_time_left_handle_frame_set(seq, timeline_frame); + SEQ_time_left_handle_frame_set(scene, seq, timeline_frame); } /* Adjust within range of strip contents. */ else if ((timeline_frame >= seq->start) && (timeline_frame <= (seq->start + seq->len))) { @@ -290,19 +290,19 @@ static void seq_split_set_left_hold_offset(Sequence *seq, int timeline_frame) seq->start += timeline_frame - seq->start; seq->anim_startofs += seq->len - 1; seq->len = 1; - SEQ_time_left_handle_frame_set(seq, timeline_frame); - SEQ_time_right_handle_frame_set(seq, right_handle_backup); + SEQ_time_left_handle_frame_set(scene, seq, timeline_frame); + SEQ_time_right_handle_frame_set(scene, seq, right_handle_backup); } } -static void seq_split_set_right_hold_offset(Sequence *seq, int timeline_frame) +static void seq_split_set_right_hold_offset(const Scene *scene, Sequence *seq, int timeline_frame) { /* Adjust within range of extended stillframes before strip. */ if (timeline_frame < seq->start) { const int left_handle_backup = SEQ_time_left_handle_frame_get(seq); seq->start = timeline_frame - 1; - SEQ_time_left_handle_frame_set(seq, left_handle_backup); - SEQ_time_right_handle_frame_set(seq, timeline_frame); + SEQ_time_left_handle_frame_set(scene, seq, left_handle_backup); + SEQ_time_right_handle_frame_set(scene, seq, timeline_frame); } /* Adjust within range of strip contents. */ else if ((timeline_frame >= seq->start) && (timeline_frame <= (seq->start + seq->len))) { @@ -311,11 +311,11 @@ static void seq_split_set_right_hold_offset(Sequence *seq, int timeline_frame) } /* Adjust within range of extended stillframes after strip. */ else if ((seq->start + seq->len) < timeline_frame) { - SEQ_time_right_handle_frame_set(seq, timeline_frame); + SEQ_time_right_handle_frame_set(scene, seq, timeline_frame); } } -static void seq_split_set_right_offset(Sequence *seq, int timeline_frame) +static void seq_split_set_right_offset(const Scene *scene, Sequence *seq, int timeline_frame) { /* Adjust within range of extended stillframes before strip. */ if (timeline_frame < seq->start) { @@ -324,10 +324,10 @@ static void seq_split_set_right_offset(Sequence *seq, int timeline_frame) seq->startofs += content_offset; } - SEQ_time_right_handle_frame_set(seq, timeline_frame); + SEQ_time_right_handle_frame_set(scene, seq, timeline_frame); } -static void seq_split_set_left_offset(Sequence *seq, int timeline_frame) +static void seq_split_set_left_offset(const Scene *scene, Sequence *seq, int timeline_frame) { /* Adjust within range of extended stillframes after strip. */ if (timeline_frame > seq->start + seq->len) { @@ -336,17 +336,17 @@ static void seq_split_set_left_offset(Sequence *seq, int timeline_frame) seq->endofs += content_offset; } - SEQ_time_left_handle_frame_set(seq, timeline_frame); + SEQ_time_left_handle_frame_set(scene, seq, timeline_frame); } static bool seq_edit_split_effect_intersect_check(const Sequence *seq, const int timeline_frame) { - return timeline_frame > seq->startdisp && timeline_frame < seq->enddisp; + return timeline_frame > SEQ_time_left_handle_frame_get(seq) && + timeline_frame < SEQ_time_right_handle_frame_get(seq); } static void seq_edit_split_handle_strip_offsets(Main *bmain, Scene *scene, - ListBase *seqbase, Sequence *left_seq, Sequence *right_seq, const int timeline_frame, @@ -355,27 +355,25 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain, if (seq_edit_split_effect_intersect_check(right_seq, timeline_frame)) { switch (method) { case SEQ_SPLIT_SOFT: - seq_split_set_left_offset(right_seq, timeline_frame); + seq_split_set_left_offset(scene, right_seq, timeline_frame); break; case SEQ_SPLIT_HARD: - seq_split_set_left_hold_offset(right_seq, timeline_frame); + seq_split_set_left_hold_offset(scene, right_seq, timeline_frame); SEQ_add_reload_new_file(bmain, scene, right_seq, false); break; } - SEQ_time_update_sequence(scene, seqbase, right_seq); } if (seq_edit_split_effect_intersect_check(left_seq, timeline_frame)) { switch (method) { case SEQ_SPLIT_SOFT: - seq_split_set_right_offset(left_seq, timeline_frame); + seq_split_set_right_offset(scene, left_seq, timeline_frame); break; case SEQ_SPLIT_HARD: - seq_split_set_right_hold_offset(left_seq, timeline_frame); + seq_split_set_right_hold_offset(scene, left_seq, timeline_frame); SEQ_add_reload_new_file(bmain, scene, left_seq, false); break; } - SEQ_time_update_sequence(scene, seqbase, left_seq); } } @@ -468,10 +466,6 @@ Sequence *SEQ_edit_strip_split(Main *bmain, SEQ_collection_free(collection); - /* Sort list, so that no strip can depend on next strip in list. - * This is important for SEQ_time_update_sequence functionality. */ - SEQ_sort(&left_strips); - /* Duplicate ListBase. */ ListBase right_strips = {NULL, NULL}; SEQ_sequence_base_dupli_recursive(scene, scene, &right_strips, &left_strips, SEQ_DUPE_ALL, 0); @@ -480,18 +474,23 @@ Sequence *SEQ_edit_strip_split(Main *bmain, Sequence *right_seq = right_strips.first; Sequence *return_seq = NULL; - /* Move strips from detached `ListBase`, otherwise they can't be flagged for removal, - * SEQ_time_update_sequence can fail to update meta strips and they can't be renamed. - * This is because these functions check all strips in `Editing` to manage relationships. */ + /* Move strips from detached `ListBase`, otherwise they can't be flagged for removal. */ BLI_movelisttolist(seqbase, &left_strips); BLI_movelisttolist(seqbase, &right_strips); + /* Rename duplicated strips. This has to be done immediately after adding + * strips to seqbase, for lookup cache to work correctly. */ + Sequence *seq_rename = right_seq; + for (; seq_rename; seq_rename = seq_rename->next) { + SEQ_ensure_unique_name(seq_rename, scene); + } + /* Split strips. */ while (left_seq && right_seq) { - if (left_seq->startdisp >= timeline_frame) { + if (SEQ_time_left_handle_frame_get(left_seq) >= timeline_frame) { SEQ_edit_flag_for_removal(scene, seqbase, left_seq); } - if (right_seq->enddisp <= timeline_frame) { + else if (SEQ_time_right_handle_frame_get(right_seq) <= timeline_frame) { SEQ_edit_flag_for_removal(scene, seqbase, right_seq); } else if (return_seq == NULL) { @@ -499,20 +498,12 @@ Sequence *SEQ_edit_strip_split(Main *bmain, return_seq = right_seq; } - seq_edit_split_handle_strip_offsets( - bmain, scene, seqbase, left_seq, right_seq, timeline_frame, method); + seq_edit_split_handle_strip_offsets(bmain, scene, left_seq, right_seq, timeline_frame, method); left_seq = left_seq->next; right_seq = right_seq->next; } SEQ_edit_remove_flagged_sequences(scene, seqbase); - - /* Rename duplicated strips. */ - Sequence *seq_rename = return_seq; - for (; seq_rename; seq_rename = seq_rename->next) { - SEQ_ensure_unique_name(seq_rename, scene); - } - SEQ_animation_restore_original(scene, &fcurves_original_backup); return return_seq; diff --git a/source/blender/sequencer/intern/strip_relations.c b/source/blender/sequencer/intern/strip_relations.c index 1899cc99263..4acf2763ce5 100644 --- a/source/blender/sequencer/intern/strip_relations.c +++ b/source/blender/sequencer/intern/strip_relations.c @@ -47,7 +47,8 @@ static bool seq_relations_check_depend(Sequence *seq, Sequence *cur) } /* sequences are not intersecting in time, assume no dependency exists between them */ - if (cur->enddisp < seq->startdisp || cur->startdisp > seq->enddisp) { + if (SEQ_time_right_handle_frame_get(cur) < SEQ_time_left_handle_frame_get(seq) || + SEQ_time_left_handle_frame_get(cur) > SEQ_time_right_handle_frame_get(seq)) { return false; } @@ -290,8 +291,8 @@ static void sequencer_all_free_anim_ibufs(Editing *ed, } else { /* Limit frame range to meta strip. */ - meta_range[0] = max_ii(frame_range[0], seq->startdisp); - meta_range[1] = min_ii(frame_range[1], seq->enddisp); + meta_range[0] = max_ii(frame_range[0], SEQ_time_left_handle_frame_get(seq)); + meta_range[1] = min_ii(frame_range[1], SEQ_time_right_handle_frame_get(seq)); } sequencer_all_free_anim_ibufs(ed, &seq->seqbase, timeline_frame, meta_range); @@ -345,7 +346,7 @@ bool SEQ_relations_check_scene_recursion(Scene *scene, ReportList *reports) RPT_WARNING, "Recursion detected in video sequencer. Strip %s at frame %d will not be rendered", recursive_seq->name + 2, - recursive_seq->startdisp); + SEQ_time_left_handle_frame_get(recursive_seq)); LISTBASE_FOREACH (Sequence *, seq, &ed->seqbase) { if (seq->type != SEQ_TYPE_SCENE && sequencer_seq_generates_image(seq)) { diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c index e4f7a5e87e8..25d4f08be82 100644 --- a/source/blender/sequencer/intern/strip_time.c +++ b/source/blender/sequencer/intern/strip_time.c @@ -27,6 +27,7 @@ #include "SEQ_time.h" #include "SEQ_transform.h" +#include "sequencer.h" #include "strip_time.h" #include "utils.h" @@ -37,7 +38,7 @@ float seq_give_frame_index(Sequence *seq, float timeline_frame) int end = seq->start + seq->len - 1; if (seq->type & SEQ_TYPE_EFFECT) { - end = seq->enddisp; + end = SEQ_time_right_handle_frame_get(seq); } if (end < sta) { @@ -89,7 +90,7 @@ static int metaseq_end(Sequence *metaseq) return metaseq->start + metaseq->len - metaseq->endofs; } -static void seq_update_sound_bounds_recursive_impl(Scene *scene, +static void seq_update_sound_bounds_recursive_impl(const Scene *scene, Sequence *metaseq, int start, int end) @@ -131,33 +132,31 @@ static void seq_update_sound_bounds_recursive_impl(Scene *scene, } } -void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq) +void seq_update_sound_bounds_recursive(const Scene *scene, Sequence *metaseq) { seq_update_sound_bounds_recursive_impl( scene, metaseq, metaseq_start(metaseq), metaseq_end(metaseq)); } -static void seq_time_update_sequence_bounds(Scene *scene, Sequence *seq) +/* Update meta strip content start and end, update sound playback range. */ +void SEQ_time_update_meta_strip_range(const Scene *scene, Sequence *seq_meta) { - seq->startdisp = seq->start + seq->startofs; - seq->enddisp = seq->start + seq->len - seq->endofs; - - if (seq->type == SEQ_TYPE_META) { - seq_update_sound_bounds_recursive(scene, seq); + if (seq_meta == NULL) { + return; } -} -static void seq_time_update_meta_strip(Scene *scene, Sequence *seq_meta) -{ if (BLI_listbase_is_empty(&seq_meta->seqbase)) { return; } + const int strip_start = SEQ_time_left_handle_frame_get(seq_meta); + const int strip_end = SEQ_time_right_handle_frame_get(seq_meta); + int min = MAXFRAME * 2; int max = -MAXFRAME * 2; LISTBASE_FOREACH (Sequence *, seq, &seq_meta->seqbase) { - min = min_ii(seq->startdisp, min); - max = max_ii(seq->enddisp, max); + min = min_ii(SEQ_time_left_handle_frame_get(seq), min); + max = max_ii(SEQ_time_right_handle_frame_get(seq), max); } seq_meta->start = min + seq_meta->anim_startofs; @@ -166,144 +165,54 @@ static void seq_time_update_meta_strip(Scene *scene, Sequence *seq_meta) seq_meta->len -= seq_meta->anim_endofs; seq_update_sound_bounds_recursive(scene, seq_meta); -} - -void SEQ_time_update_meta_strip_range(Scene *scene, Sequence *seq_meta) -{ - if (seq_meta == NULL) { - return; - } - - seq_time_update_meta_strip(scene, seq_meta); /* Prevent meta-strip to move in timeline. */ - SEQ_time_left_handle_frame_set(seq_meta, seq_meta->startdisp); - SEQ_time_right_handle_frame_set(seq_meta, seq_meta->enddisp); + SEQ_time_left_handle_frame_set(scene, seq_meta, strip_start); + SEQ_time_right_handle_frame_set(scene, seq_meta, strip_end); } -void SEQ_time_update_sequence(Scene *scene, ListBase *seqbase, Sequence *seq) +void seq_time_effect_range_set(Sequence *seq) { - Sequence *seqm; - - /* Check all meta-strips recursively. */ - seqm = seq->seqbase.first; - while (seqm) { - if (seqm->seqbase.first) { - SEQ_time_update_sequence(scene, &seqm->seqbase, seqm); - } - seqm = seqm->next; + if (seq->seq1 && seq->seq2) { /* 2 - input effect. */ + seq->startdisp = max_ii(SEQ_time_left_handle_frame_get(seq->seq1), + SEQ_time_left_handle_frame_get(seq->seq2)); + seq->enddisp = min_ii(SEQ_time_right_handle_frame_get(seq->seq1), + SEQ_time_right_handle_frame_get(seq->seq2)); } - - /* effects and meta: automatic start and end */ - if (seq->type & SEQ_TYPE_EFFECT) { - if (seq->seq1) { - seq->startofs = seq->endofs = 0; - if (seq->seq3) { - seq->start = seq->startdisp = max_iii( - seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp); - seq->enddisp = min_iii(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp); - } - else if (seq->seq2) { - seq->start = seq->startdisp = max_ii(seq->seq1->startdisp, seq->seq2->startdisp); - seq->enddisp = min_ii(seq->seq1->enddisp, seq->seq2->enddisp); - } - else { - seq->start = seq->startdisp = seq->seq1->startdisp; - seq->enddisp = seq->seq1->enddisp; - } - /* we can't help if strips don't overlap, it won't give useful results. - * but at least ensure 'len' is never negative which causes bad bugs elsewhere. */ - if (seq->enddisp < seq->startdisp) { - /* simple start/end swap */ - seq->start = seq->enddisp; - seq->enddisp = seq->startdisp; - seq->startdisp = seq->start; - seq->flag |= SEQ_INVALID_EFFECT; - } - else { - seq->flag &= ~SEQ_INVALID_EFFECT; - } - - seq->len = seq->enddisp - seq->startdisp; - } - else { - seq_time_update_sequence_bounds(scene, seq); - } + else if (seq->seq1) { /* Single input effect. */ + seq->startdisp = SEQ_time_right_handle_frame_get(seq->seq1); + seq->enddisp = SEQ_time_left_handle_frame_get(seq->seq1); } - else if (seq->type == SEQ_TYPE_META) { - seq_time_update_meta_strip(scene, seq); + else if (seq->seq2) { /* Strip may be missing one of inputs. */ + seq->startdisp = SEQ_time_right_handle_frame_get(seq->seq2); + seq->enddisp = SEQ_time_left_handle_frame_get(seq->seq2); } - else { - seq_time_update_sequence_bounds(scene, seq); - } - - Editing *ed = SEQ_editing_get(scene); - /* Strip is inside meta strip */ - if (seqbase != &ed->seqbase) { - Sequence *meta = SEQ_get_meta_by_seqbase(&ed->seqbase, seqbase); - SEQ_time_update_meta_strip_range(scene, meta); + if (seq->startdisp > seq->enddisp) { + SWAP(int, seq->startdisp, seq->enddisp); } - seq_time_update_sequence_bounds(scene, seq); + /* Values unusable for effects, these should be always 0. */ + seq->startofs = seq->endofs = seq->anim_startofs = seq->anim_endofs = 0; } -static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq) +/* Update strip startdisp and enddisp (n-input effects have no len to calculate these). */ +void seq_time_update_effects_strip_range(const Scene *scene, SeqCollection *effects) { - Sequence *subseq; - bool do_update = false; - - /* recurse downwards to see if this seq depends on the changed seq */ - - if (seq == NULL) { - return false; - } - - if (seq == changed_seq) { - do_update = true; - } - - for (subseq = seq->seqbase.first; subseq; subseq = subseq->next) { - if (update_changed_seq_recurs(scene, subseq, changed_seq)) { - do_update = true; - } - } - - if (seq->seq1) { - if (update_changed_seq_recurs(scene, seq->seq1, changed_seq)) { - do_update = true; - } - } - if (seq->seq2 && (seq->seq2 != seq->seq1)) { - if (update_changed_seq_recurs(scene, seq->seq2, changed_seq)) { - do_update = true; - } - } - if (seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2)) { - if (update_changed_seq_recurs(scene, seq->seq3, changed_seq)) { - do_update = true; - } - } - - if (do_update) { - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); - SEQ_time_update_sequence(scene, seqbase, seq); + if (effects == NULL) { + return; } - return do_update; -} - -void SEQ_time_update_recursive(Scene *scene, Sequence *changed_seq) -{ - Editing *ed = SEQ_editing_get(scene); Sequence *seq; - - if (ed == NULL) { - return; + /* First pass: Update length of immediate effects. */ + SEQ_ITERATOR_FOREACH (seq, effects) { + seq_time_effect_range_set(seq); } - for (seq = ed->seqbase.first; seq; seq = seq->next) { - update_changed_seq_recurs(scene, seq, changed_seq); + /* Second pass: Recursive call to update effects in chain and in order, so they inherit length + * correctly. */ + SEQ_ITERATOR_FOREACH (seq, effects) { + seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq)); } } @@ -342,12 +251,14 @@ int SEQ_time_find_next_prev_edit(Scene *scene, } if (do_center) { - seq_frames[0] = (seq->startdisp + seq->enddisp) / 2; + seq_frames[0] = (SEQ_time_left_handle_frame_get(seq) + + SEQ_time_right_handle_frame_get(seq)) / + 2; seq_frames_tot = 1; } else { - seq_frames[0] = seq->startdisp; - seq_frames[1] = seq->enddisp; + seq_frames[0] = SEQ_time_left_handle_frame_get(seq); + seq_frames[1] = SEQ_time_right_handle_frame_get(seq); seq_frames_tot = 2; } @@ -431,11 +342,11 @@ void SEQ_timeline_expand_boundbox(const ListBase *seqbase, rctf *rect) } LISTBASE_FOREACH (Sequence *, seq, seqbase) { - if (rect->xmin > seq->startdisp - 1) { - rect->xmin = seq->startdisp - 1; + if (rect->xmin > SEQ_time_left_handle_frame_get(seq) - 1) { + rect->xmin = SEQ_time_left_handle_frame_get(seq) - 1; } - if (rect->xmax < seq->enddisp + 1) { - rect->xmax = seq->enddisp + 1; + if (rect->xmax < SEQ_time_right_handle_frame_get(seq) + 1) { + rect->xmax = SEQ_time_right_handle_frame_get(seq) + 1; } if (rect->ymax < seq->machine) { rect->ymax = seq->machine; @@ -507,7 +418,8 @@ void seq_time_gap_info_get(const Scene *scene, bool SEQ_time_strip_intersects_frame(const Sequence *seq, const int timeline_frame) { - return (seq->startdisp <= timeline_frame) && (seq->enddisp > timeline_frame); + return (SEQ_time_left_handle_frame_get(seq) <= timeline_frame) && + (SEQ_time_right_handle_frame_get(seq) > timeline_frame); } bool SEQ_time_has_left_still_frames(const Sequence *seq) @@ -525,21 +437,36 @@ bool SEQ_time_has_still_frames(const Sequence *seq) return SEQ_time_has_right_still_frames(seq) || SEQ_time_has_left_still_frames(seq); } -int SEQ_time_left_handle_frame_get(Sequence *seq) +int SEQ_time_left_handle_frame_get(const Sequence *seq) { + if (seq->seq1 || seq->seq2) { + return seq->startdisp; + } + return seq->start + seq->startofs; } -int SEQ_time_right_handle_frame_get(Sequence *seq) + +int SEQ_time_right_handle_frame_get(const Sequence *seq) { + if (seq->seq1 || seq->seq2) { + return seq->enddisp; + } + return seq->start + seq->len - seq->endofs; } -void SEQ_time_left_handle_frame_set(Sequence *seq, int val) +void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int val) { seq->startofs = val - seq->start; + seq->startdisp = val; /* Only to make files usable in older versions. */ + SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq)); + seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq)); } -void SEQ_time_right_handle_frame_set(Sequence *seq, int val) +void SEQ_time_right_handle_frame_set(const Scene *scene, Sequence *seq, int val) { seq->endofs = seq->start + seq->len - val; + seq->enddisp = val; /* Only to make files usable in older versions. */ + SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq)); + seq_time_update_effects_strip_range(scene, seq_sequence_lookup_effects_by_seq(scene, seq)); } diff --git a/source/blender/sequencer/intern/strip_time.h b/source/blender/sequencer/intern/strip_time.h index c96a016e646..7a75aeac1a6 100644 --- a/source/blender/sequencer/intern/strip_time.h +++ b/source/blender/sequencer/intern/strip_time.h @@ -14,9 +14,10 @@ extern "C" { struct ListBase; struct Scene; struct Sequence; +struct SeqCollection; float seq_give_frame_index(struct Sequence *seq, float timeline_frame); -void seq_update_sound_bounds_recursive(struct Scene *scene, struct Sequence *metaseq); +void seq_update_sound_bounds_recursive(const struct Scene *scene, struct Sequence *metaseq); /* Describes gap between strips in timeline. */ typedef struct GapInfo { @@ -37,6 +38,8 @@ void seq_time_gap_info_get(const struct Scene *scene, struct ListBase *seqbase, int initial_frame, struct GapInfo *r_gap_info); +void seq_time_effect_range_set(Sequence *seq); +void seq_time_update_effects_strip_range(const struct Scene *scene, struct SeqCollection *effects); #ifdef __cplusplus } diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c index 8ff577240d6..ebf317eff05 100644 --- a/source/blender/sequencer/intern/strip_transform.c +++ b/source/blender/sequencer/intern/strip_transform.c @@ -25,6 +25,9 @@ #include "SEQ_time.h" #include "SEQ_transform.h" +#include "sequencer.h" +#include "strip_time.h" + #include "CLG_log.h" static CLG_LogRef LOG = {"seq.strip_transform"}; @@ -86,16 +89,16 @@ bool SEQ_transform_seqbase_isolated_sel_check(ListBase *seqbase) return true; } -void SEQ_transform_handle_xlimits(Sequence *seq, int leftflag, int rightflag) +void SEQ_transform_handle_xlimits(const Scene *scene, Sequence *seq, int leftflag, int rightflag) { if (leftflag) { if (SEQ_time_left_handle_frame_get(seq) >= SEQ_time_right_handle_frame_get(seq)) { - SEQ_time_left_handle_frame_set(seq, SEQ_time_right_handle_frame_get(seq) - 1); + SEQ_time_left_handle_frame_set(scene, seq, SEQ_time_right_handle_frame_get(seq) - 1); } if (SEQ_transform_single_image_check(seq) == 0) { if (SEQ_time_left_handle_frame_get(seq) >= seq_tx_get_end(seq)) { - SEQ_time_left_handle_frame_set(seq, seq_tx_get_end(seq) - 1); + SEQ_time_left_handle_frame_set(scene, seq, seq_tx_get_end(seq) - 1); } /* TODO: This doesn't work at the moment. */ @@ -112,12 +115,12 @@ void SEQ_transform_handle_xlimits(Sequence *seq, int leftflag, int rightflag) if (rightflag) { if (SEQ_time_right_handle_frame_get(seq) <= SEQ_time_left_handle_frame_get(seq)) { - SEQ_time_right_handle_frame_set(seq, SEQ_time_left_handle_frame_get(seq) + 1); + SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(seq) + 1); } if (SEQ_transform_single_image_check(seq) == 0) { if (SEQ_time_right_handle_frame_get(seq) <= seq_tx_get_start(seq)) { - SEQ_time_right_handle_frame_set(seq, seq_tx_get_start(seq) + 1); + SEQ_time_right_handle_frame_set(scene, seq, seq_tx_get_start(seq) + 1); } } } @@ -129,7 +132,7 @@ void SEQ_transform_handle_xlimits(Sequence *seq, int leftflag, int rightflag) } } -void SEQ_transform_fix_single_image_seq_offsets(Sequence *seq) +void SEQ_transform_fix_single_image_seq_offsets(const Scene *scene, Sequence *seq) { int left, start, offset; if (!SEQ_transform_single_image_check(seq)) { @@ -142,8 +145,8 @@ void SEQ_transform_fix_single_image_seq_offsets(Sequence *seq) start = seq->start; if (start != left) { offset = left - start; - SEQ_time_left_handle_frame_set(seq, SEQ_time_left_handle_frame_get(seq) - offset); - SEQ_time_right_handle_frame_set(seq, SEQ_time_right_handle_frame_get(seq) - offset); + SEQ_time_left_handle_frame_set(scene, seq, SEQ_time_left_handle_frame_get(seq) - offset); + SEQ_time_right_handle_frame_set(scene, seq, SEQ_time_right_handle_frame_get(seq) - offset); seq->start += offset; } } @@ -156,7 +159,8 @@ bool SEQ_transform_sequence_can_be_translated(Sequence *seq) bool SEQ_transform_test_overlap_seq_seq(Sequence *seq1, Sequence *seq2) { return (seq1 != seq2 && seq1->machine == seq2->machine && - ((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp)) == 0); + ((SEQ_time_right_handle_frame_get(seq1) <= SEQ_time_left_handle_frame_get(seq2)) || + (SEQ_time_left_handle_frame_get(seq1) >= SEQ_time_right_handle_frame_get(seq2))) == 0); } bool SEQ_transform_test_overlap(ListBase *seqbasep, Sequence *test) @@ -180,9 +184,6 @@ void SEQ_transform_translate_sequence(Scene *evil_scene, Sequence *seq, int delt return; } - SEQ_offset_animdata(evil_scene, seq, delta); - seq->start += delta; - /* Meta strips requires special handling: their content is to be translated, and then frame range * of the meta is to be updated for the updated content. */ if (seq->type == SEQ_TYPE_META) { @@ -190,16 +191,21 @@ void SEQ_transform_translate_sequence(Scene *evil_scene, Sequence *seq, int delt for (seq_child = seq->seqbase.first; seq_child; seq_child = seq_child->next) { SEQ_transform_translate_sequence(evil_scene, seq_child, delta); } - /* Ensure that meta bounds are updated, but this function prevents resets seq->start and - * start/end point in timeline. */ - SEQ_time_update_meta_strip_range(evil_scene, seq); /* Move meta start/end points. */ - SEQ_time_left_handle_frame_set(seq, seq->startdisp + delta); - SEQ_time_right_handle_frame_set(seq, seq->enddisp + delta); + SEQ_time_left_handle_frame_set(evil_scene, seq, SEQ_time_left_handle_frame_get(seq) + delta); + SEQ_time_right_handle_frame_set(evil_scene, seq, SEQ_time_right_handle_frame_get(seq) + delta); + } + else { /* All other strip types. */ + seq->start += delta; + /* Only to make files usable in older versions. */ + seq->startdisp = SEQ_time_left_handle_frame_get(seq); + seq->enddisp = SEQ_time_right_handle_frame_get(seq); } - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(evil_scene)); - SEQ_time_update_sequence(evil_scene, seqbase, seq); + SEQ_offset_animdata(evil_scene, seq, delta); + SEQ_time_update_meta_strip_range(evil_scene, seq_sequence_lookup_meta_by_seq(evil_scene, seq)); + seq_time_update_effects_strip_range(evil_scene, + seq_sequence_lookup_effects_by_seq(evil_scene, seq)); } bool SEQ_transform_seqbase_shuffle_ex(ListBase *seqbasep, @@ -211,16 +217,12 @@ bool SEQ_transform_seqbase_shuffle_ex(ListBase *seqbasep, BLI_assert(ELEM(channel_delta, -1, 1)); test->machine += channel_delta; - SEQ_time_update_sequence(evil_scene, seqbasep, test); while (SEQ_transform_test_overlap(seqbasep, test)) { if ((channel_delta > 0) ? (test->machine >= MAXSEQ) : (test->machine < 1)) { break; } test->machine += channel_delta; - - /* XXX: I don't think this is needed since were only moving vertically, Campbell. */ - SEQ_time_update_sequence(evil_scene, seqbasep, test); } if (!SEQ_valid_strip_channel(test)) { @@ -228,19 +230,18 @@ bool SEQ_transform_seqbase_shuffle_ex(ListBase *seqbasep, * nicer to move it to the end */ Sequence *seq; - int new_frame = test->enddisp; + int new_frame = SEQ_time_right_handle_frame_get(test); for (seq = seqbasep->first; seq; seq = seq->next) { if (seq->machine == orig_machine) { - new_frame = max_ii(new_frame, seq->enddisp); + new_frame = max_ii(new_frame, SEQ_time_right_handle_frame_get(seq)); } } test->machine = orig_machine; - new_frame = new_frame + (test->start - test->startdisp); /* adjust by the startdisp */ + new_frame = new_frame + + (test->start - SEQ_time_left_handle_frame_get(test)); /* adjust by the startdisp */ SEQ_transform_translate_sequence(evil_scene, test, new_frame - test->start); - - SEQ_time_update_sequence(evil_scene, seqbasep, test); return false; } @@ -252,61 +253,57 @@ bool SEQ_transform_seqbase_shuffle(ListBase *seqbasep, Sequence *test, Scene *ev return SEQ_transform_seqbase_shuffle_ex(seqbasep, test, evil_scene, 1); } -static int shuffle_seq_time_offset_test(SeqCollection *strips_to_shuffle, - ListBase *seqbasep, - char dir) +static bool shuffle_seq_test_overlap(const Sequence *seq1, const Sequence *seq2, const int offset) { - int offset = 0; - Sequence *seq; - - SEQ_ITERATOR_FOREACH (seq, strips_to_shuffle) { - LISTBASE_FOREACH (Sequence *, seq_other, seqbasep) { - if (!SEQ_transform_test_overlap_seq_seq(seq, seq_other)) { - continue; - } - if (SEQ_relation_is_effect_of_strip(seq_other, seq)) { - continue; - } - if (UNLIKELY(SEQ_collection_has_strip(seq_other, strips_to_shuffle))) { - CLOG_WARN(&LOG, - "Strip overlaps with itself or another strip, that is to be shuffled. " - "This should never happen."); - continue; - } - if (dir == 'L') { - offset = min_ii(offset, seq_other->startdisp - seq->enddisp); - } - else { - offset = max_ii(offset, seq_other->enddisp - seq->startdisp); - } - } - } - return offset; + return ( + seq1 != seq2 && seq1->machine == seq2->machine && + ((SEQ_time_right_handle_frame_get(seq1) + offset <= SEQ_time_left_handle_frame_get(seq2)) || + (SEQ_time_left_handle_frame_get(seq1) + offset >= SEQ_time_right_handle_frame_get(seq2))) == + 0); } -static int shuffle_seq_time_offset(SeqCollection *strips_to_shuffle, - ListBase *seqbasep, - Scene *scene, - char dir) +static int shuffle_seq_time_offset_get(SeqCollection *strips_to_shuffle, + ListBase *seqbasep, + char dir) { - int ofs = 0; - int tot_ofs = 0; + int offset = 0; Sequence *seq; - while ((ofs = shuffle_seq_time_offset_test(strips_to_shuffle, seqbasep, dir))) { + bool all_conflicts_resolved = false; + + while (!all_conflicts_resolved) { + all_conflicts_resolved = true; SEQ_ITERATOR_FOREACH (seq, strips_to_shuffle) { - /* seq_test_overlap only tests display values */ - seq->startdisp += ofs; - seq->enddisp += ofs; - } + LISTBASE_FOREACH (Sequence *, seq_other, seqbasep) { + if (!shuffle_seq_test_overlap(seq, seq_other, offset)) { + continue; + } + if (SEQ_relation_is_effect_of_strip(seq_other, seq)) { + continue; + } + if (UNLIKELY(SEQ_collection_has_strip(seq_other, strips_to_shuffle))) { + CLOG_WARN(&LOG, + "Strip overlaps with itself or another strip, that is to be shuffled. " + "This should never happen."); + continue; + } - tot_ofs += ofs; - } + all_conflicts_resolved = false; - SEQ_ITERATOR_FOREACH (seq, strips_to_shuffle) { - SEQ_time_update_sequence(scene, seqbasep, seq); /* corrects dummy startdisp/enddisp values */ + if (dir == 'L') { + offset = min_ii(offset, + SEQ_time_left_handle_frame_get(seq_other) - + SEQ_time_right_handle_frame_get(seq)); + } + else { + offset = max_ii(offset, + SEQ_time_right_handle_frame_get(seq_other) - + SEQ_time_left_handle_frame_get(seq)); + } + } + } } - return tot_ofs; + return offset; } bool SEQ_transform_seqbase_shuffle_time(SeqCollection *strips_to_shuffle, @@ -315,8 +312,8 @@ bool SEQ_transform_seqbase_shuffle_time(SeqCollection *strips_to_shuffle, ListBase *markers, const bool use_sync_markers) { - int offset_l = shuffle_seq_time_offset(strips_to_shuffle, seqbasep, evil_scene, 'L'); - int offset_r = shuffle_seq_time_offset(strips_to_shuffle, seqbasep, evil_scene, 'R'); + int offset_l = shuffle_seq_time_offset_get(strips_to_shuffle, seqbasep, 'L'); + int offset_r = shuffle_seq_time_offset_get(strips_to_shuffle, seqbasep, 'R'); int offset = (-offset_l < offset_r) ? offset_l : offset_r; if (offset) { @@ -346,9 +343,8 @@ void SEQ_transform_offset_after_frame(Scene *scene, const int timeline_frame) { LISTBASE_FOREACH (Sequence *, seq, seqbase) { - if (seq->startdisp >= timeline_frame) { + if (SEQ_time_left_handle_frame_get(seq) >= timeline_frame) { SEQ_transform_translate_sequence(scene, seq, delta); - SEQ_time_update_sequence(scene, seqbase, seq); SEQ_relations_invalidate_cache_preprocessed(scene, seq); } } diff --git a/source/blender/sequencer/intern/utils.c b/source/blender/sequencer/intern/utils.c index 0cf47420d8f..260f82310fb 100644 --- a/source/blender/sequencer/intern/utils.c +++ b/source/blender/sequencer/intern/utils.c @@ -39,55 +39,9 @@ #include "multiview.h" #include "proxy.h" +#include "sequencer.h" #include "utils.h" -void SEQ_sort(ListBase *seqbase) -{ - if (seqbase == NULL) { - return; - } - - /* all strips together per kind, and in order of y location ("machine") */ - ListBase inputbase, effbase; - Sequence *seq, *seqt; - - BLI_listbase_clear(&inputbase); - BLI_listbase_clear(&effbase); - - while ((seq = BLI_pophead(seqbase))) { - - if (seq->type & SEQ_TYPE_EFFECT) { - seqt = effbase.first; - while (seqt) { - if (seqt->machine >= seq->machine) { - BLI_insertlinkbefore(&effbase, seqt, seq); - break; - } - seqt = seqt->next; - } - if (seqt == NULL) { - BLI_addtail(&effbase, seq); - } - } - else { - seqt = inputbase.first; - while (seqt) { - if (seqt->machine >= seq->machine) { - BLI_insertlinkbefore(&inputbase, seqt, seq); - break; - } - seqt = seqt->next; - } - if (seqt == NULL) { - BLI_addtail(&inputbase, seq); - } - } - } - - BLI_movelisttolist(seqbase, &inputbase); - BLI_movelisttolist(seqbase, &effbase); -} - typedef struct SeqUniqueInfo { Sequence *seq; char name_src[SEQ_NAME_MAXSTR]; @@ -414,20 +368,18 @@ const Sequence *SEQ_get_topmost_sequence(const Scene *scene, int frame) return best_seq; } -ListBase *SEQ_get_seqbase_by_seq(ListBase *seqbase, Sequence *seq) +ListBase *SEQ_get_seqbase_by_seq(const Scene *scene, Sequence *seq) { - Sequence *iseq; - ListBase *lb = NULL; + Editing *ed = SEQ_editing_get(scene); + ListBase *main_seqbase = &ed->seqbase; + Sequence *seq_meta = seq_sequence_lookup_meta_by_seq(scene, seq); - for (iseq = seqbase->first; iseq; iseq = iseq->next) { - if (seq == iseq) { - return seqbase; - } - if (iseq->seqbase.first && (lb = SEQ_get_seqbase_by_seq(&iseq->seqbase, seq))) { - return lb; - } + if (seq_meta != NULL) { + return &seq_meta->seqbase; + } + if (BLI_findindex(main_seqbase, seq) >= 0) { + return main_seqbase; } - return NULL; } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 890872a06bc..dec1260ad1d 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -1400,6 +1400,14 @@ void WM_jobs_callbacks(struct wmJob *, void (*update)(void *), void (*endjob)(void *)); +void WM_jobs_callbacks_ex(wmJob *wm_job, + wm_jobs_start_callback startjob, + void (*initjob)(void *), + void (*update)(void *), + void (*endjob)(void *), + void (*completed)(void *), + void (*canceled)(void *)); + /** * If job running, the same owner gave it a new job. * if different owner starts existing startjob, it suspends itself @@ -1426,6 +1434,7 @@ void WM_jobs_kill_all_except(struct wmWindowManager *wm, const void *owner); void WM_jobs_kill_type(struct wmWindowManager *wm, const void *owner, int job_type); bool WM_jobs_has_running(const struct wmWindowManager *wm); +bool WM_jobs_has_running_type(const struct wmWindowManager *wm, int job_type); void WM_job_main_thread_lock_acquire(struct wmJob *job); void WM_job_main_thread_lock_release(struct wmJob *job); diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index b44cf9e48b8..d5c4d07e9ed 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -87,6 +87,16 @@ struct wmJob { * Executed in main thread. */ void (*endjob)(void *); + /** + * Called when job is stopped normally, i.e. by simply completing the startjob function. + * Executed in main thread. + */ + void (*completed)(void *); + /** + * Called when job is stopped abnormally, i.e. when stop=true but ready=false. + * Executed in main thread. + */ + void (*canceled)(void *); /** Running jobs each have own timer */ double timestep; @@ -344,10 +354,23 @@ void WM_jobs_callbacks(wmJob *wm_job, void (*update)(void *), void (*endjob)(void *)) { + WM_jobs_callbacks_ex(wm_job, startjob, initjob, update, endjob, NULL, NULL); +} + +void WM_jobs_callbacks_ex(wmJob *wm_job, + wm_jobs_start_callback startjob, + void (*initjob)(void *), + void (*update)(void *), + void (*endjob)(void *), + void (*completed)(void *), + void (*canceled)(void *)) +{ wm_job->startjob = startjob; wm_job->initjob = initjob; wm_job->update = update; wm_job->endjob = endjob; + wm_job->completed = completed; + wm_job->canceled = canceled; } static void *do_job_thread(void *job_v) @@ -465,6 +488,24 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job) } } +static void wm_job_end(wmJob *wm_job) +{ + BLI_assert_msg(BLI_thread_is_main(), "wm_job_end should only be called from the main thread"); + if (wm_job->endjob) { + wm_job->endjob(wm_job->run_customdata); + } + + /* Do the final callback based on whether the job was run to completion or not. + * Not all jobs have the same way of signaling cancellation (i.e. rendering stops when + * `G.is_break == true`, but doesn't set any wm_job properties to cancel the WM job). */ + const bool was_canceled = wm_job->stop || G.is_break; + void (*final_callback)(void *) = (wm_job->ready && !was_canceled) ? wm_job->completed : + wm_job->canceled; + if (final_callback) { + final_callback(wm_job->run_customdata); + } +} + static void wm_job_free(wmWindowManager *wm, wmJob *wm_job) { BLI_remlink(&wm->jobs, wm_job); @@ -485,10 +526,7 @@ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job) WM_job_main_thread_lock_release(wm_job); BLI_threadpool_end(&wm_job->threads); WM_job_main_thread_lock_acquire(wm_job); - - if (wm_job->endjob) { - wm_job->endjob(wm_job->run_customdata); - } + wm_job_end(wm_job); } if (wm_job->wt) { @@ -600,9 +638,7 @@ void wm_jobs_timer(wmWindowManager *wm, wmTimer *wt) } if (wm_job->ready) { - if (wm_job->endjob) { - wm_job->endjob(wm_job->run_customdata); - } + wm_job_end(wm_job); /* free own data */ wm_job->run_free(wm_job->run_customdata); @@ -670,3 +706,13 @@ bool WM_jobs_has_running(const wmWindowManager *wm) return false; } + +bool WM_jobs_has_running_type(const struct wmWindowManager *wm, int job_type) +{ + LISTBASE_FOREACH (wmJob *, wm_job, &wm->jobs) { + if (wm_job->running && wm_job->job_type == job_type) { + return true; + } + } + return false; +} diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 1fa5e64093f..acacbd77f9e 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -445,7 +445,10 @@ bool WM_keymap_poll(bContext *C, wmKeyMap *keymap) * When developing a customized Blender though you may want empty keymaps. */ if (!U.app_template[0] && /* Fallback key-maps may be intentionally empty, don't flood the output. */ - !BLI_str_endswith(keymap->idname, " (fallback)")) { + !BLI_str_endswith(keymap->idname, " (fallback)") && + /* This is an exception which may be empty. + * Longer term we might want a flag to indicate an empty key-map is intended. */ + !STREQ(keymap->idname, "Node Tool: Tweak")) { CLOG_WARN(WM_LOG_KEYMAPS, "empty keymap '%s'", keymap->idname); } } diff --git a/source/blender/windowmanager/intern/wm_keymap_utils.c b/source/blender/windowmanager/intern/wm_keymap_utils.c index 5a35570296a..531da3cf2e8 100644 --- a/source/blender/windowmanager/intern/wm_keymap_utils.c +++ b/source/blender/windowmanager/intern/wm_keymap_utils.c @@ -270,6 +270,9 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname) break; } } + else if (STRPREFIX(opname, "CURVES_SCULPT_OT")) { + km = WM_keymap_find_all(wm, "Sculpt Curves", 0, 0); + } else if (STRPREFIX(opname, "MBALL_OT")) { km = WM_keymap_find_all(wm, "Metaball", 0, 0); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 307d3282659..7b768bd8c70 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3898,7 +3898,7 @@ static void gesture_box_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_box"); - /* XXX TODO: zoom border should perhaps map rightmouse to zoom out instead of in+cancel */ + /* XXX TODO: zoom border should perhaps map right-mouse to zoom out instead of in+cancel. */ WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom_border"); WM_modalkeymap_assign(keymap, "IMAGE_OT_render_border"); WM_modalkeymap_assign(keymap, "IMAGE_OT_view_zoom_border"); |