Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2022-01-12BLI: Refactor vector types & functions to use templatesClément Foucault
This patch implements the vector types (i.e:`float2`) by making heavy usage of templating. All vector functions are now outside of the vector classes (inside the `blender::math` namespace) and are not vector size dependent for the most part. In the ongoing effort to make shaders less GL centric, we are aiming to share more code between GLSL and C++ to avoid code duplication. ####Motivations: - We are aiming to share UBO and SSBO structures between GLSL and C++. This means we will use many of the existing vector types and others we currently don't have (uintX, intX). All these variations were asking for many more code duplication. - Deduplicate existing code which is duplicated for each vector size. - We also want to share small functions. Which means that vector functions should be static and not in the class namespace. - Reduce friction to use these types in new projects due to their incompleteness. - The current state of the `BLI_(float|double|mpq)(2|3|4).hh` is a bit of a let down. Most clases are incomplete, out of sync with each others with different codestyles, and some functions that should be static are not (i.e: `float3::reflect()`). ####Upsides: - Still support `.x, .y, .z, .w` for readability. - Compact, readable and easilly extendable. - All of the vector functions are available for all the vectors types and can be restricted to certain types. Also template specialization let us define exception for special class (like mpq). - With optimization ON, the compiler unroll the loops and performance is the same. ####Downsides: - Might impact debugability. Though I would arge that the bugs are rarelly caused by the vector class itself (since the operations are quite trivial) but by the type conversions. - Might impact compile time. I did not saw a significant impact since the usage is not really widespread. - Functions needs to be rewritten to support arbitrary vector length. For instance, one can't call `len_squared_v3v3` in `math::length_squared()` and call it a day. - Type cast does not work with the template version of the `math::` vector functions. Meaning you need to manually cast `float *` and `(float *)[3]` to `float3` for the function calls. i.e: `math::distance_squared(float3(nearest.co), positions[i]);` - Some parts might loose in readability: `float3::dot(v1.normalized(), v2.normalized())` becoming `math::dot(math::normalize(v1), math::normalize(v2))` But I propose, when appropriate, to use `using namespace blender::math;` on function local or file scope to increase readability. `dot(normalize(v1), normalize(v2))` ####Consideration: - Include back `.length()` method. It is quite handy and is more C++ oriented. - I considered the GLM library as a candidate for replacement. It felt like too much for what we need and would be difficult to extend / modify to our needs. - I used Macros to reduce code in operators declaration and potential copy paste bugs. This could reduce debugability and could be reverted. - This touches `delaunay_2d.cc` and the intersection code. I would like to know @howardt opinion on the matter. - The `noexcept` on the copy constructor of `mpq(2|3)` is being removed. But according to @JacquesLucke it is not a real problem for now. I would like to give a huge thanks to @JacquesLucke who helped during this and pushed me to reduce the duplication further. Reviewed By: brecht, sergey, JacquesLucke Differential Revision: https://developer.blender.org/D13791
2022-01-12Revert "BLI: Refactor vector types & functions to use templates"Clément Foucault
Includes unwanted changes This reverts commit 46e049d0ce2bce2f53ddc41a0dbbea2969d00a5d.
2022-01-12BLI: Refactor vector types & functions to use templatesClment Foucault
This patch implements the vector types (i.e:`float2`) by making heavy usage of templating. All vector functions are now outside of the vector classes (inside the `blender::math` namespace) and are not vector size dependent for the most part. In the ongoing effort to make shaders less GL centric, we are aiming to share more code between GLSL and C++ to avoid code duplication. ####Motivations: - We are aiming to share UBO and SSBO structures between GLSL and C++. This means we will use many of the existing vector types and others we currently don't have (uintX, intX). All these variations were asking for many more code duplication. - Deduplicate existing code which is duplicated for each vector size. - We also want to share small functions. Which means that vector functions should be static and not in the class namespace. - Reduce friction to use these types in new projects due to their incompleteness. - The current state of the `BLI_(float|double|mpq)(2|3|4).hh` is a bit of a let down. Most clases are incomplete, out of sync with each others with different codestyles, and some functions that should be static are not (i.e: `float3::reflect()`). ####Upsides: - Still support `.x, .y, .z, .w` for readability. - Compact, readable and easilly extendable. - All of the vector functions are available for all the vectors types and can be restricted to certain types. Also template specialization let us define exception for special class (like mpq). - With optimization ON, the compiler unroll the loops and performance is the same. ####Downsides: - Might impact debugability. Though I would arge that the bugs are rarelly caused by the vector class itself (since the operations are quite trivial) but by the type conversions. - Might impact compile time. I did not saw a significant impact since the usage is not really widespread. - Functions needs to be rewritten to support arbitrary vector length. For instance, one can't call `len_squared_v3v3` in `math::length_squared()` and call it a day. - Type cast does not work with the template version of the `math::` vector functions. Meaning you need to manually cast `float *` and `(float *)[3]` to `float3` for the function calls. i.e: `math::distance_squared(float3(nearest.co), positions[i]);` - Some parts might loose in readability: `float3::dot(v1.normalized(), v2.normalized())` becoming `math::dot(math::normalize(v1), math::normalize(v2))` But I propose, when appropriate, to use `using namespace blender::math;` on function local or file scope to increase readability. `dot(normalize(v1), normalize(v2))` ####Consideration: - Include back `.length()` method. It is quite handy and is more C++ oriented. - I considered the GLM library as a candidate for replacement. It felt like too much for what we need and would be difficult to extend / modify to our needs. - I used Macros to reduce code in operators declaration and potential copy paste bugs. This could reduce debugability and could be reverted. - This touches `delaunay_2d.cc` and the intersection code. I would like to know @howardt opinion on the matter. - The `noexcept` on the copy constructor of `mpq(2|3)` is being removed. But according to @JacquesLucke it is not a real problem for now. I would like to give a huge thanks to @JacquesLucke who helped during this and pushed me to reduce the duplication further. Reviewed By: brecht, sergey, JacquesLucke Differential Revision: https://developer.blender.org/D13791
2022-01-12Revert "BLI: Refactor vector types & functions to use templates"Clément Foucault
Reverted because the commit removes a lot of commits. This reverts commit a2c1c368af48644fa8995ecbe7138cc0d7900c30.
2022-01-12BLI: Refactor vector types & functions to use templatesClément Foucault
This patch implements the vector types (i.e:float2) by making heavy usage of templating. All vector functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. In the ongoing effort to make shaders less GL centric, we are aiming to share more code between GLSL and C++ to avoid code duplication. Motivations: - We are aiming to share UBO and SSBO structures between GLSL and C++. This means we will use many of the existing vector types and others we currently don't have (uintX, intX). All these variations were asking for many more code duplication. - Deduplicate existing code which is duplicated for each vector size. - We also want to share small functions. Which means that vector functions should be static and not in the class namespace. - Reduce friction to use these types in new projects due to their incompleteness. - The current state of the BLI_(float|double|mpq)(2|3|4).hh is a bit of a let down. Most clases are incomplete, out of sync with each others with different codestyles, and some functions that should be static are not (i.e: float3::reflect()). Upsides: - Still support .x, .y, .z, .w for readability. - Compact, readable and easilly extendable. - All of the vector functions are available for all the vectors types and can be restricted to certain types. Also template specialization let us define exception for special class (like mpq). - With optimization ON, the compiler unroll the loops and performance is the same. Downsides: - Might impact debugability. Though I would arge that the bugs are rarelly caused by the vector class itself (since the operations are quite trivial) but by the type conversions. - Might impact compile time. I did not saw a significant impact since the usage is not really widespread. - Functions needs to be rewritten to support arbitrary vector length. For instance, one can't call len_squared_v3v3 in math::length_squared() and call it a day. - Type cast does not work with the template version of the math:: vector functions. Meaning you need to manually cast float * and (float *)[3] to float3 for the function calls. i.e: math::distance_squared(float3(nearest.co), positions[i]); - Some parts might loose in readability: float3::dot(v1.normalized(), v2.normalized()) becoming math::dot(math::normalize(v1), math::normalize(v2)) But I propose, when appropriate, to use using namespace blender::math; on function local or file scope to increase readability. dot(normalize(v1), normalize(v2)) Consideration: - Include back .length() method. It is quite handy and is more C++ oriented. - I considered the GLM library as a candidate for replacement. It felt like too much for what we need and would be difficult to extend / modify to our needs. - I used Macros to reduce code in operators declaration and potential copy paste bugs. This could reduce debugability and could be reverted. - This touches delaunay_2d.cc and the intersection code. I would like to know @Howard Trickey (howardt) opinion on the matter. - The noexcept on the copy constructor of mpq(2|3) is being removed. But according to @Jacques Lucke (JacquesLucke) it is not a real problem for now. I would like to give a huge thanks to @Jacques Lucke (JacquesLucke) who helped during this and pushed me to reduce the duplication further. Reviewed By: brecht, sergey, JacquesLucke Differential Revision: http://developer.blender.org/D13791
2022-01-07Cleanup: remove redundant const qualifiers for POD typesCampbell Barton
MSVC used to warn about const mismatch for arguments passed by value. Remove these as newer versions of MSVC no longer show this warning.
2021-12-26Docs: Add to and cleanup attribute API docsHans Goudey
Most of the comment block is similar to the text in the source code documentation wiki. It's helpful to have some text in a header file too, so it's closer for programmers already looking at the code. This also uses more consistent syntax and wording in the comments about the attribute API in `GeometryComponent`. Ref T93753 Differential Revision: https://developer.blender.org/D13661
2021-12-23Fix: Potential use after scope in curve to mesh nodeHans Goudey
I don't think this has been visible, since I only ran into it after changing other code that affected this. However, some attributes can keep a reference to the source component to use when tagging caches dirty (like the position attribute tagging the normals dirty). Here, the component was created inside a function, then the attributes were used afterwards. Also add some comments warning about this in the header file.
2021-12-07Cleanup: move public doc-strings into headers for 'blenkernel'Campbell Barton
- Added space below non doc-string comments to make it clear these aren't comments for the symbols directly below them. - Use doxy sections for some headers. - Minor improvements to doc-strings. Ref T92709
2021-12-06Cleanup: remove unnecessary extern template implementationsJacques Lucke
This technique isn't really necessary anymore, because unity builds avoid instantiating the same template too many times already.
2021-11-30Fix: Missing handling of dynamic instance attribute sizeHans Goudey
The attributes need to be reallocated when the size changes. Differential Revision: https://developer.blender.org/D13390
2021-11-16Geometry Nodes: refactor virtual array systemJacques Lucke
Goals of this refactor: * Simplify creating virtual arrays. * Simplify passing virtual arrays around. * Simplify converting between typed and generic virtual arrays. * Reduce memory allocations. As a quick reminder, a virtual arrays is a data structure that behaves like an array (i.e. it can be accessed using an index). However, it may not actually be stored as array internally. The two most important implementations of virtual arrays are those that correspond to an actual plain array and those that have the same value for every index. However, many more implementations exist for various reasons (interfacing with legacy attributes, unified iterator over all points in multiple splines, ...). With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and `GVMutableArray`) can be used like "normal values". They typically live on the stack. Before, they were usually inside a `std::unique_ptr`. This makes passing them around much easier. Creation of new virtual arrays is also much simpler now due to some constructors. Memory allocations are reduced by making use of small object optimization inside the core types. Previously, `VArray` was a class with virtual methods that had to be overridden to change the behavior of a the virtual array. Now,`VArray` has a fixed size and has no virtual methods. Instead it contains a `VArrayImpl` that is similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly, unless a new virtual array implementation is added. To support the small object optimization for many `VArrayImpl` classes, a new `blender::Any` type is added. It is similar to `std::any` with two additional features. It has an adjustable inline buffer size and alignment. The inline buffer size of `std::any` can't be relied on and is usually too small for our use case here. Furthermore, `blender::Any` can store additional user-defined type information without increasing the stack size. Differential Revision: https://developer.blender.org/D12986
2021-11-02Fix T92652: Joining curves breaks point attribute orderHans Goudey
Currently the curve to mesh node relies on the order of attributes being the same on every spline. This is a worthwhile assumption, because it will allow removing the attribute name storage duplication on every spline in the future. However, the join geometry node broke this order, since it just created new attributes without any regard to the order. To fix this, I added a "reorder" step after all the merged attributes have been created, the types have been joined, etc. It should be possible to change this code so that the attributes are added with the right order in the first place, but I would like to do that after refactoring spline attribute storage, and not for 3.0. Differential Revision: https://developer.blender.org/D13074
2021-10-29Geometry Nodes: do cache invalidation after writing attributesJacques Lucke
This is a better and more general fix for T92511 and T92508 than the ones that I committed before. Previously, we tagged caches dirty when first accessing attributes. This led to incorrect caches when under some circumstances. Now cache invalidation is part of `OutputAttribute.save()`. A nice side benefit of this change is that it may make things more efficient in some cases, because we don't invalidate caches when they don't have to be invalidated. Differential Revision: https://developer.blender.org/D13009
2021-10-24Cleanup: quiet asan warning because of uninitialized variableJacques Lucke
2021-10-20Cleanup: Add check whether to remove an anonymous atttributeHans Goudey
Add a higher level check that can be used instead of checking whether the attribute ID is anonymous and checking whether it has any strong references.
2021-10-05Cleanup: use doxygen sectionsCampbell Barton
2021-10-03Cleanup: move as_span method out of headerJacques Lucke
This method does not have to be in a header and results in a relatively large number of symbols to be generated (42).
2021-10-03Cleanup: use extern templates for typed output attributeJacques Lucke
This is very similar to rBa812fe8ceb75fd2b. This time the number of symbols decreases further from 1335 to 928. Compile time of the distribute node decreases from ~2.4s to ~2.3s.
2021-10-03Cleanup: use movable output attribute instead of optionalJacques Lucke
This simplifies the code a bit and improves compile times a bit.
2021-10-03Cleanup: make typed output attribute movableJacques Lucke
This comes at a small performance cost due to an additional memory allocation, but that is not significant currently.
2021-10-03Cleanup: move AttributeIDRef and OutputAttribute methods out of classJacques Lucke
This makes the classes easier to read and simplifies testing the compile time impact of defining these methods in the header.
2021-09-23Geometry Nodes: simplify looping over attributes in geometry setJacques Lucke
This adds three new methods: * `InstancesComponent::foreach_reference_as_geometry(...)` * `GeometrySet::attribute_foreach(...)` * `GeometrySet::gather_attributes_for_propagation(...)` The goal is that these iteration primitives can be used in places where we use more specialized iterators currently. Differential Revision: https://developer.blender.org/D12613
2021-09-23Geometry Nodes: add utility to print an attribute id.Jacques Lucke
2021-09-16Cleanup: Remove unnecessary manual of move constructorHans Goudey
Turns out this isn't actually necessary.
2021-09-16Geometry Nodes: Simplify using OutputAttribute in a vectorHans Goudey
Store the optional temporary span storage as a unique_ptr and move it in the move constructor, to avoid the need to add a special move constructor that clears the "show_warning" fields from it. Maybe this is very slightly slower, but we'll need this class less often in the future anyway.
2021-09-09Geometry Nodes: fields and anonymous attributesJacques Lucke
This implements the initial core framework for fields and anonymous attributes (also see T91274). The new functionality is hidden behind the "Geometry Nodes Fields" feature flag. When enabled in the user preferences, the following new nodes become available: `Position`, `Index`, `Normal`, `Set Position` and `Attribute Capture`. Socket inspection has not been updated to work with fields yet. Besides these changes at the user level, this patch contains the ground work for: * building and evaluating fields at run-time (`FN_fields.hh`) and * creating and accessing anonymous attributes on geometry (`BKE_anonymous_attribute.h`). For evaluating fields we use a new so called multi-function procedure (`FN_multi_function_procedure.hh`). It allows composing multi-functions in arbitrary ways and supports efficient evaluation as is required by fields. See `FN_multi_function_procedure.hh` for more details on how this evaluation mechanism can be used. A new `AttributeIDRef` has been added which allows handling named and anonymous attributes in the same way in many places. Hans and I worked on this patch together. Differential Revision: https://developer.blender.org/D12414
2021-06-09Geometry Nodes: Copy spline attributes in the curve resample nodeHans Goudey
Previously only point domain attributes were copied to the result curve.
2021-06-02Geometry Nodes: Allow reading converted attribute directly from splineHans Goudey
Often it would be beneficial to avoid the virtual array implementation in `geometry_component_curve.cc` that flattens an attribute for every spline and instead read an attribute separately for every input spline. This commit implements functions to do that. The downside is some code duplication-- we now have two places handling this conversion. However, we can head in this general direction for the attribute API anyway and support accessing attributes in smaller contiguous chunks where necessary. No functional changes in this commit. Differential Revision: https://developer.blender.org/D11456
2021-05-20Cleanup: spellingCampbell Barton
2021-05-19Geometry Nodes: Support for dynamic attributes on curve splinesHans Goudey
With this patch you will be able to add and remove attributes from curve data inside of geometry nodes. The following is currently implemented: * Adding attributes with any data type to splines or spline points. * Support for working with multiple splines at the same time. * Interaction with the three builtin point attributes. * Resampling attributes in the resample node. The following is not implemented in this patch: * Joining attributes when joining splines with the join geometry node. * Domain interpolation between spline and point domains. * More efficient ways to call attribute operations once per spline. Differential Revision: https://developer.blender.org/D11251
2021-05-14Cleanup: Move attribute code to attribute headerHans Goudey
This code in the geometry set header was not directly related to geometry sets, it makes more sense in the attribute access header. This makes it clearer that code for geometry components uses attribute code, rather than the other way around. It also allows adding more functionality to `BKE_attribute_access.hh` that depends on these things without including `BKE_geometry_set.hh` there.
2021-04-23Geometry Nodes: warn when output attribute has not been savedJacques Lucke
2021-04-17Geometry Nodes: use virtual arrays in internal attribute apiJacques Lucke
A virtual array is a data structure that is similar to a normal array in that its elements can be accessed by an index. However, a virtual array does not have to be a contiguous array internally. Instead, its elements can be layed out arbitrarily while element access happens through a virtual function call. However, the virtual array data structures are designed so that the virtual function call can be avoided in cases where it could become a bottleneck. Most commonly, a virtual array is backed by an actual array/span or is a single value internally, that is the same for every index. Besides those, there are many more specialized virtual arrays like the ones that provides vertex positions based on the `MVert` struct or vertex group weights. Not all attributes used by geometry nodes are stored in simple contiguous arrays. To provide uniform access to all kinds of attributes, the attribute API has to provide virtual array functionality that hides the implementation details of attributes. Before this refactor, the attribute API provided its own virtual array implementation as part of the `ReadAttribute` and `WriteAttribute` types. That resulted in unnecessary code duplication with the virtual array system. Even worse, it bound many algorithms used by geometry nodes to the specifics of the attribute API, even though they could also use different data sources (such as data from sockets, default values, later results of expressions, ...). This refactor removes the `ReadAttribute` and `WriteAttribute` types and replaces them with `GVArray` and `GVMutableArray` respectively. The `GV` stands for "generic virtual". The "generic" means that the data type contained in those virtual arrays is only known at run-time. There are the corresponding statically typed types `VArray<T>` and `VMutableArray<T>` as well. No regressions are expected from this refactor. It does come with one improvement for users. The attribute API can convert the data type on write now. This is especially useful when writing to builtin attributes like `material_index` with e.g. the Attribute Math node (which usually just writes to float attributes, while `material_index` is an integer attribute). Differential Revision: https://developer.blender.org/D10994
2021-03-21Functions: refactor virtual array data structuresJacques Lucke
When a function is executed for many elements (e.g. per point) it is often the case that some parameters are different for every element and other parameters are the same (there are some more less common cases). To simplify writing such functions one can use a "virtual array". This is a data structure that has a value for every index, but might not be stored as an actual array internally. Instead, it might be just a single value or is computed on the fly. There are various tradeoffs involved when using this data structure which are mentioned in `BLI_virtual_array.hh`. It is called "virtual", because it uses inheritance and virtual methods. Furthermore, there is a new virtual vector array data structure, which is an array of vectors. Both these types have corresponding generic variants, which can be used when the data type is not known at compile time. This is typically the case when building a somewhat generic execution system. The function system used these virtual data structures before, but now they are more versatile. I've done this refactor in preparation for the attribute processor and other features of geometry nodes. I moved the typed virtual arrays to blenlib, so that they can be used independent of the function system. One open question for me is whether all the generic data structures (and `CPPType`) should be moved to blenlib as well. They are well isolated and don't really contain any business logic. That can be done later if necessary.
2021-02-16Geometry Nodes: move some attribute utilities to blenkernelJacques Lucke
I need to access these utilities from modifier code as well. Therefore, they should not live in the nodes module.
2021-02-06UI: Fix Typos in Comments and Docsluzpaz
Approximately 91 spelling corrections, almost all in comments. Differential Revision: https://developer.blender.org/D10288 Reviewed by Harley Acheson
2021-01-21Geometry Nodes: new Attribute Sample Texture nodeJacques Lucke
This node allows sampling a texture for every vertex based on some mapping attribute. Typical attribute names are the name of a uv map (e.g. "UVMap") and "position". However, every attribute that can be converted to a vector implicitly is supported. It should be noted that as of right now, uv map attributes can only be accessed after a Point Distribute node. Ref T82584. Differential Revision: https://developer.blender.org/D10121
2021-01-13Geometry Nodes: cleanup attribute usageJacques Lucke
Now that typed attribute wrappers don't need to own the attribute anymore, many `std::move` calls can be removed.
2021-01-13Geometry Nodes: support optional ownership for typed attributesJacques Lucke
This will simplify some code in an upcoming commit and will be useful for T83793.
2021-01-12Geometry Nodes: support reading from spans of WriteAttributeJacques Lucke
Previously, the span returned by `WriteAttribute`s might not contain the current value of the attribute for performance reasons. To avoid some bugs, the span now always contains the old values (they might have to be copied over from the internal storage, dependending on how the attribute is stored). The old behavior is still available with the `get_span_for_write_only` method. The span that it returns might not contain the current attribute values. Therefore, it should only be used when you want to overwrite an attribute without looking at the old values.
2020-12-17Geometry Nodes: Make random attribute node stableHans Goudey
Currently, the random attribute node doesn't work well for most workflows because for any change in the input data it outputs completely different results. This patch adds an implicit seed attribute input to the node, referred to by "id". The attribute is hashed for each element using the CPPType system's hash method, meaning the attribute can have any data type. Supporting any data type is also important so any attribute can be copied into the "id" attribute and used as a seed. The "id" attribute is an example of a "reserved name" attribute, meaning attributes with this name can be used implicitly by nodes like the random attribute node. Although it makes it a bit more difficult to dig deeper, using the name implicitly rather than exposing it as an input should make the system more accessible and predictable. Differential Revision: https://developer.blender.org/D9832
2020-12-16Geometry Nodes: Boolean attribute typeHans Goudey
This adds a boolean attribute and custom data type, to be used in the point separate node. It also adds it as supported data types in the random attribute and attribute fill nodes. There are more clever ways of storing a boolean attribute that make more sense in certain situations-- sets, bitfields, and others, this commit keeps it simple, saving those changes for when there is a proper use case for them. In any case, we will still probably always want the idea of a boolean attribute. Differential Revision: https://developer.blender.org/D9818
2020-12-16Cleanup: remove redundant struct declarationsCampbell Barton
2020-12-03Geometry Nodes: improve support for Color attributesJacques Lucke
* Add typed attribute accessors for color attributes. * Support implicit conversions between colors and floats.
2020-12-03Geometry Nodes: add custom data type getter for attribute accessorJacques Lucke
This is just an utility method, that avoids that the caller has to do the conversion every time it is necessary.
2020-12-02Geometry Nodes: initial scattering and geometry nodesJacques Lucke
This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix