Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/BKE_geometry_set.hh
| Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
| template<> struct DefaultHash<GeometryComponentType> { | template<> struct DefaultHash<GeometryComponentType> { | ||||
| uint64_t operator()(const GeometryComponentType &value) const | uint64_t operator()(const GeometryComponentType &value) const | ||||
| { | { | ||||
| return (uint64_t)value; | return (uint64_t)value; | ||||
| } | } | ||||
| }; | }; | ||||
| } // namespace blender | } // namespace blender | ||||
| class GeometryComponent; | |||||
| /** | |||||
| * An #OutputAttributePtr wraps a #WriteAttributePtr that might not be stored in its final | |||||
| * destination yet. Therefore, once the attribute has been filled with data, the #save method has | |||||
| * to be called, to store the attribute where it belongs (possibly by replacing an existing | |||||
| * attribute with the same name). | |||||
| * | |||||
| * This is useful for example in the Attribute Color Ramp node, when the same attribute name is | |||||
| * used as input and output. Typically the input is a float attribute, and the output is a color. | |||||
| * Those two attributes cannot exist at the same time, due to a name collision. To handle this | |||||
| * situation well, first the output colors have to be computed before the input floats are deleted. | |||||
| * Therefore, the outputs have to be written to a temporary buffer that replaces the existing | |||||
| * attribute once all computations are done. | |||||
| */ | |||||
| class OutputAttributePtr { | |||||
| private: | |||||
| blender::bke::WriteAttributePtr attribute_; | |||||
| public: | |||||
| OutputAttributePtr() = default; | |||||
| OutputAttributePtr(blender::bke::WriteAttributePtr attribute); | |||||
| OutputAttributePtr(GeometryComponent &component, | |||||
| AttributeDomain domain, | |||||
| std::string name, | |||||
| CustomDataType data_type); | |||||
| ~OutputAttributePtr(); | |||||
| /* Returns false, when this wrapper is empty. */ | |||||
| operator bool() const | |||||
| { | |||||
| return static_cast<bool>(attribute_); | |||||
| } | |||||
| /* Get a reference to the underlying #WriteAttribute. */ | |||||
| blender::bke::WriteAttribute &get() | |||||
| { | |||||
| BLI_assert(attribute_); | |||||
| return *attribute_; | |||||
| } | |||||
| blender::bke::WriteAttribute &operator*() | |||||
| { | |||||
| return *attribute_; | |||||
| } | |||||
| blender::bke::WriteAttribute *operator->() | |||||
| { | |||||
| return attribute_.get(); | |||||
| } | |||||
| void save(); | |||||
| void apply_span_and_save(); | |||||
| }; | |||||
| /** | /** | ||||
| * This is the base class for specialized geometry component types. | * This is the base class for specialized geometry component types. | ||||
| */ | */ | ||||
| class GeometryComponent { | class GeometryComponent { | ||||
| private: | private: | ||||
| /* The reference count has two purposes. When it becomes zero, the component is freed. When it is | /* The reference count has two purposes. When it becomes zero, the component is freed. When it is | ||||
| * larger than one, the component becomes immutable. */ | * larger than one, the component becomes immutable. */ | ||||
| mutable std::atomic<int> users_ = 1; | mutable std::atomic<int> users_ = 1; | ||||
| ▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | blender::bke::TypedReadAttribute<T> attribute_get_constant_for_read(const AttributeDomain domain, | ||||
| const T &value) const | const T &value) const | ||||
| { | { | ||||
| const blender::fn::CPPType &cpp_type = blender::fn::CPPType::get<T>(); | const blender::fn::CPPType &cpp_type = blender::fn::CPPType::get<T>(); | ||||
| const CustomDataType type = blender::bke::cpp_type_to_custom_data_type(cpp_type); | const CustomDataType type = blender::bke::cpp_type_to_custom_data_type(cpp_type); | ||||
| return this->attribute_get_constant_for_read(domain, type, &value); | return this->attribute_get_constant_for_read(domain, type, &value); | ||||
| } | } | ||||
| /** | /** | ||||
| * Returns the attribute with the given parameters if it exists. | * If an attribute with the given params exist, it is returned. | ||||
| * If an exact match does not exist, other attributes with the same name are deleted and a new | * If no attribute with the given name exists, it is created and returned. | ||||
| * attribute is created if possible. | * If an attribute with the given name but different domain or type exists, a temporary attribute | ||||
| * is created that has to be saved after the output has been computed. This avoids deleting | |||||
| * another attribute, before a computation is finished. | |||||
| * | |||||
| * This might return no attribute when the attribute cannot exist on the component. | |||||
| */ | */ | ||||
| blender::bke::WriteAttributePtr attribute_try_ensure_for_write( | OutputAttributePtr attribute_try_get_for_output(const blender::StringRef attribute_name, | ||||
| const blender::StringRef attribute_name, | |||||
| const AttributeDomain domain, | const AttributeDomain domain, | ||||
| const CustomDataType data_type); | const CustomDataType data_type); | ||||
| }; | }; | ||||
| template<typename T> | template<typename T> | ||||
| inline constexpr bool is_geometry_component_v = std::is_base_of_v<GeometryComponent, T>; | inline constexpr bool is_geometry_component_v = std::is_base_of_v<GeometryComponent, T>; | ||||
| /** | /** | ||||
| * A geometry set contains zero or more geometry components. There is at most one component of each | * A geometry set contains zero or more geometry components. There is at most one component of each | ||||
| * type. Individual components might be shared between multiple geometries. Shared components are | * type. Individual components might be shared between multiple geometries. Shared components are | ||||
| ▲ Show 20 Lines • Show All 200 Lines • Show Last 20 Lines | |||||