Age | Commit message (Collapse) | Author |
|
This patch introduces a new `CacheMutex` which makes it easy to implement
lazily computed caches in e.g. `Curves`. For more details see `BLI_cache_mutex.hh`.
Differential Revision: https://developer.blender.org/D16419
|
|
This patch contains an initial set of nodes to access basic
mesh topology information, as explored in T100020.
The nodes allow six direct topology mappings for meshes:
- **Corner -> Face** The face a corner is in, the index in the face
- **Vertex -> Edge** Choose an edge attached to the vertex
- **Vertex -> Corner** Choose a corner attached to the vertex
- **Corner -> Edge** The next and previous edge at each face corner
- **Corner -> Vertex** The vertex associated with a corner
- **Corner -> Corner** Offset a corner index within a face
And two new topology mappings for curves:
- **Curve -> Points** Choose a point within a curve
- **Point -> Curve** The curve a point is in, the index in the curve
The idea is that some of the 16 possible mesh mappings are more
important, and that this is a useful set of nodes to start exploring
this area. For mappings with an arbitrary number of connections, we
must sort them and use an index to choose a single element, because
geometry nodes does not support list fields. Note that the sort
index has repeating behavior as it goes over the "Total" number of
connections, and negative sort indices choose from the end.
Currently which of the "start" elements is used is determined by the
field context, so the "Field at Index" and "Interpolate Domain" nodes
will be quite important. Also, currently the "Sort Index" inputs are
clamped to the number of connections.
One important feature that isn't implemented here is using the winding
order for the output elements. This can be a separate mode for some
of these nodes. It will be optional because of the performance impact.
There are several todos for separate commits after this:
- Rename "Control Point Neighbors" to be consistent with this naming
- Version away the "Vertex Neighbors" node which is fully redundant now
- Implement a special case for when no weights are used for performance
- De-duplicating some of the sorting logic between the nodes
- Improve performance and memory use of topology mappings
- Look into caching some of the mappings on meshes
Differential Revision: https://developer.blender.org/D16029
|
|
Use function style casts in C++ headers & source.
|
|
Correct interpolation of integer POD types for Catmull Rom
interpolation as implemented in eaf416693dcb.
**Problem description**
`attribute_math::DefaultMixer<T>::mix_in()` assumes/asserts positive
weights but the basis function for Catmull-Rom splines generates
negative weights (see image in revision). Passing negative weights will
yield correct result as sum(weights) = 1 (after multiplication by 0.5)
but the assert is still triggered in debug builds. This patch adjusts
the behavior by extending the mix functions with mix4(). The benefit
of using mix#() over a DefaultMixer is that the result no longer needs
to be divided by the weight sum, instead utilizing that the basis weight
sum is constant (see plot).
**Changes**
* Added mix4() and updated catmull_rom::interpolate() to use it.
* Removed TODOs from catmull_rom functions.
* Moved mix definitions to be ordered as 2, 3, 4 in the header.
**Implementation specifics**
`catmull_rom::interpolate()` uses a constexpr to differentiate between
POD types which multiplies the result with 0.5 after weighting the
values, this reduces the number of multiplications for 1D, 2D, 3D
vectors (https://godbolt.org/z/8M1z9Pxx6). While this could be
considered unnecessary, I didn't want to change the original behavior
as it could influence performance (did not measure performance here
as this should ensure the logic is ~identical for FP types).
Differential Revision: https://developer.blender.org/D15997
|
|
While this worked, the result for curves with a resolution of zero was
just a single evaluated point, which isn't useful or intuitive. Using
the attribute validation from 8934f00ac5701ea34, make sure users
can't set values 0 or less.
|
|
We expect some builtin attributes to have positive values or values
within a certain range, but currently there some cases where users
can set attributes to arbitrary values: the store named attribute node,
and the output attributes of the geometry nodes modifier. The set
material index node also needs validation.
This patch adds an `AttributeValidator` to the attribute API, which
can be used to correct values from these untrusted inputs if necessary.
As an alternative to D15548, this approach makes it much easier to
understand when validation is being applied, without the need to add
arguments to every attribute API method or complicate the virtual
array system.
Currently validation is provided with a multi-function. That integrates
well with the field evaluations that set these values now, but it could
be wrapped to be friendlier to other areas of Blender in the future.
The Python API is not handled here either. Currently I would prefer to
wait until we can integrate the C++ and C attribute APIs better before
addressing that.
Fixes T100952
Differential Revision: https://developer.blender.org/D15990
|
|
The trim functionality is implemented in the geometry module, and
generalized a bit to be potentially useful for bisecting in the future.
The implementation is based on a helper type called `IndexRangeCyclic`
which allows iteration over all control points between two points on a
curve.
Catmull Rom curves are now supported-- trimmed without resampling first.
However, maintaining the exact shape is not possible. NURBS splines are
still converted to polylines using the evaluated curve concept.
Performance is equivalent or faster then a 3.1 build with regards to
node timings. Compared to 3.3 and 3.2, it's easy to observe test cases
where the node is at least 3 or 4 times faster.
Differential Revision: https://developer.blender.org/D14481
|
|
|
|
Add to comments in curves header, fix typo in attribute header.
Ref D14481
|
|
|
|
|
|
|
|
Previously, curves sculpt tools only worked on original data. This was
very limiting, because one could effectively only sculpt the curves when
all procedural effects were turned off. This patch adds support for curves
sculpting while looking the result of procedural effects (like deformation
based on the surface mesh). This functionality is also known as "crazy space"
support in Blender.
For more details see D15407.
Differential Revision: https://developer.blender.org/D15407
|
|
These mutable pointers present problems with ownership in relation to
proper copy-on-write for attributes. The simplest solution is to just
remove them and retrieve the layers from `CustomData` when they are
needed. This also removes the complexity and redundancy of having to
update the pointers as the curves change. A similar change will apply
to meshes and point clouds.
One downside of this change is that it makes random access with RNA
slower. However, it's simple to just use the RNA attribute API instead,
which is unaffected. In this patch I updated Cycles to do that. With
the future attribute CoW changes, this generic approach makes sense
because Cycles can just request ownership of the existing arrays.
Differential Revision: https://developer.blender.org/D15486
|
|
Previously, things like materials, symmetry, and selection options
stored on `Curves` weren't copied to the result in nodes like the
subdivide and resample nodes. Now they are, which fixes some
unexpected behavior and allows visualization of the sculpt mode
selection.
In the realize instances and join nodes the behavior is the same as
for meshes, the parameters are taken from the first (top) input.
I also refactored some functions to return a `CurvesGeometry` by-value,
which makes it the responsibility of the node to copy the parameters.
That should make the algorithms more reusable in other situations.
Differential Revision: https://developer.blender.org/D15408
|
|
Currently, there are two attribute API. The first, defined in `BKE_attribute.h` is
accessible from RNA and C code. The second is implemented with `GeometryComponent`
and is only accessible in C++ code. The second is widely used, but only being
accessible through the `GeometrySet` API makes it awkward to use, and even impossible
for types that don't correspond directly to a geometry component like `CurvesGeometry`.
This patch adds a new attribute API, designed to replace the `GeometryComponent`
attribute API now, and to eventually replace or be the basis of the other one.
The basic idea is that there is an `AttributeAccessor` class that allows code to
interact with a set of attributes owned by some geometry. The accessor itself has
no ownership. `AttributeAccessor` is a simple type that can be passed around by
value. That makes it easy to return it from functions and to store it in containers.
For const-correctness, there is also a `MutableAttributeAccessor` that allows
changing individual and can add or remove attributes.
Currently, `AttributeAccessor` is composed of two pointers. The first is a pointer
to the owner of the attribute data. The second is a pointer to a struct with
function pointers, that is similar to a virtual function table. The functions
know how to access attributes on the owner.
The actual attribute access for geometries is still implemented with the `AttributeProvider`
pattern, which makes it easy to support different sources of attributes on a
geometry and simplifies dealing with built-in attributes.
There are different ways to get an attribute accessor for a geometry:
* `GeometryComponent.attributes()`
* `CurvesGeometry.attributes()`
* `bke::mesh_attributes(const Mesh &)`
* `bke::pointcloud_attributes(const PointCloud &)`
All of these also have a `_for_write` variant that returns a `MutabelAttributeAccessor`.
Differential Revision: https://developer.blender.org/D15280
|
|
This commit moves the subdivide curve node implementation to the
geometry module, changes it to work on the new curves data-block,
and adds support for Catmull Rom curves. Internally I also added
support for a curve domain selection. That isn't used, but it's
nice to have the option anyway.
Users should notice better performance as well, since we can avoid
many small allocations, and there is no conversion to and from the
old curve type.
The code uses a similar structure to the resample node (60a6fbf5b599)
and the set type node (9e393fc2f125). The resample curves node can be
restructured to be more similar to this soon though.
Differential Revision: https://developer.blender.org/D15334
|
|
This utility struct is useful outside of sculpting code as well.
|
|
|
|
`curve_segment_num` -> `segments_num`.
The "curve" prefix is reduntant for a function in the curve namespace.
|
|
Add a method to remove points from the new curves type, just like
the existing curve removal function. No functional changes are expected.
The code is simpler because all data is just stored as attributes, but
also different because the point data for all curves is stored in the same
arrays.
Similar performance improvements as other commits in T95443 are
expected, expecially for cases where there are many small curves.
Differential Revision: https://developer.blender.org/D15130
|
|
This commit ports the "Set Spline Type" node to the new curves type.
Performance should be improved in similar ways to the other refactors
from the conversion task (T95443). Converting to and from Catmull Rom
curves is now supported. There are a few cases where a lot of work can
be skipped: when the number of points doesn't change, and when the
types already match the goal type.
The refactor has a few other explicit goals as well:
- Don't count on initialization of attribute arrays when they are
first allocated.
- Avoid copying the entire data-block when possible.
- Make decisions about which attributes to copy when changing curves
more obvious.
- Use higher-level methods to copy data between curve points.
- Optimize for the common cases of single types and full selections.
- Process selected curves of the same types in the same loop.
The Bezier to NURBS conversion is written by Piotr Makal (@pmakal).
Differential Revision: https://developer.blender.org/D14769
|
|
This implements the new way to attach curves to a mesh surface using
a uv map (based on the recent discussion in T95776).
The curves data block now not only stores a reference to the surface object
but also a name of a uv map on that object. Having a uv map is optional
for most operations, but it will be required later for animation (when the
curves are supposed to be deformed based on deformation of the surface).
The "Empty Hair" operator in the Add menu sets the uv map name automatically
if possible. It's possible to start working without a uv map and to attach the
curves to a uv map later on. It's also possible to reattach the curves to a new
uv map using the "Curves > Snap to Nearest Surface" operator in curves sculpt
mode.
Note, the implementation to do the reverse lookup from uv to a position on the
surface is trivial and inefficient now. A more efficient data structure will be
implemented separately soon.
Differential Revision: https://developer.blender.org/D15125
|
|
- CustomDataType -> eCustomDataType
- CustomDataMask -> eCustomDataMask
- AttributeDomain -> eAttrDomain
- NamedAttributeUsage -> eNamedAttrUsage
|
|
This commit adds a float selection to curve control points or curves,
a sculpt tool to paint the selection, and uses the selection influence
in the existing sculpt brushes.
The selection is the inverse of the "mask" from mesh sculpt mode
currently. That change is described in more detail here: T97903
Since some sculpt tools are really "per curve" tools, they use the
average point selection of all of their points. The delete brush
considers a curve selected if any of its points have a non-zero
selection.
There is a new option to choose the selection domain, which affects how
painting the selection works. You can also turn the selection off by
clicking on the active domain.
Sculpt brushes can be faster when the selection is small, because
finding selected curves or points is generally faster than the
existing brush intersection and distance checks.
The main limitation currently is that we can't see the selection in the
viewport by default. For now, to see the selection one has to add a
simple material to the curves object as shown in the differential
revision. And one has to switch to Material Preview in the 3d view.
Differential Revision: https://developer.blender.org/D14934
|
|
|
|
Contributed by @luzpaz
Differential Revision: https://developer.blender.org/D15058
|
|
Since 2d80f814cc249d26b01f, curves always have evaluated points,
but single point curves do no have any evaluated segments, and the
leading zero length isn't stored in the curves length cache.
|
|
Replace tot/amount & size with num, in keeping with T85728.
|
|
Follow conventions from T85728.
|
|
This commit moves the code for the resample curves node to the geometry
module, to allow reusing it in any editor. Split from D14870.
|
|
For example, this can be used to find the indices of all Bezier curves
inside an existing selection. The important part is that it is optimized
for the case when all curves have the same type.
|
|
|
|
When the profile only has one control point, its segment count was
determined incorrectly. There needs to be a special case for a single
control point, when there are no segments even if the curve is cyclic.
|
|
NURBS curves can be invalid when the order is less than the number
of points, or in a few other situations. Currently the evaluated data of
an invalid NURBS curve is empty. This is inconvenient because it
requires checking for empty curves when it otherwise wouldn't be
necessary. This patch replaces that fallback with copying the original
data to the evaluated points. This makes conceptual sense too, as if
the curve couldn't be evaluated-- which wouldn't necessarily delete it.
Usually the UI protects against this happening, but it's currently
possible to create an invalid curve with some operations like the
delete geometry node.
Differential Revision: https://developer.blender.org/D14837
|
|
|
|
|
|
Remembering the number of curves of every type makes it fast to know
whether processing specific to a single curve type has to be done.
This information was accessed in quite a few places, so this should be
an overall reduction in overhead for the new curves type.
The cache is computed eagerly, in other words every time after changing
the curve types. In order to reduce verbosity I added helper functions
for some common ways to set the types.
Differential Revision: https://developer.blender.org/D14732
|
|
|
|
This commit changes the Curve to Mesh node to work with `Curves`
instead of `CurveEval`. The change ends up basically completely
rewriting the node, since the different attribute storage means that
the decisions made previously don't make much sense anymore.
The main loops are now "for each attribute: for each curve combination"
rather than the other way around, with the goal of taking advantage
of the locality of curve attributes. This improvement is quite
noticeable with many small curves; I measured a 4-5x improvement
(around 4-5s to <1s) when converting millions of curves to tens of
millions of faces. I didn't obverse any change in performance compared
to 3.1 with fewer curves though.
The changes also solve an algorithmic flaw where any interpolated
attributes would be evaluated for every curve combination instead
of just once per curve. This can be a large improvement when there
are many profile curves.
The code relies heavily on a function `foreach_curve_combination`
which calculates some basic information about each combination and
calls a templated function. I made assumptions about unnecessary reads
being removed by compiler optimizations. For further performance
improvements in the future that might be an area to investigate.
Another might be using a "for a group of curves: for each attribute:
for each curve" pattern to increase the locality of memory access.
Differential Revision: https://developer.blender.org/D14642
|
|
The ported normal calculation from ceed37fc5cbb466a0 neglected to
use the tilt attribute to rotate the normals around the tangents.
This commit adds that behavior back, adding a new math header file
to avoid duplicating the rotation function for normalized axes.
Differential Revision: https://developer.blender.org/D14655
|
|
If all of the curves are poly curves, the evaluated positions are the
same as the original positions. In this case just reuse the original
positions span as the evaluated positions.
|
|
It is valid for NURBS curves to have no evaluated points in some cases.
|
|
Port the "Normal" and "Curve Tangent" nodes to the new curves data-block
to avoid the conversion to `CurveEval`. This should make them faster by
avoiding all that copying, but otherwise nothing else has changed.
This also includes a fix to move the normal mode as a built-in curve
attribute when converting to and from `CurveEval`. The attribute is
needed because the option is used implicitly in many nodes currently.
Differential Revision: https://developer.blender.org/D14609
|
|
- Use "curve" instead of "spline" in comments
- Use non-plural variable names
- Tag topology dirty after resolution modified rather than positions
- Reorder enum values to change which value is zero (and the default)
- Remove a duplicate unused variable
|
|
This operator snaps the first point of every curve to the corresponding
surface object. The shape of individual curves or their orientation is
not changed.
There are two different attachment modes:
* `Nearest`: Move each curve so that the first point is on the closest
point on the surface. This should be used when the topology of the
surface mesh changed, but the shape generally stayed the same.
* `Deform`: Use the existing attachment information that is stored
for curves to move curves to their new location when the surface
mesh was deformed. This generally does not work when the
topology changed.
The purpose of the operator is to help setup the "ground truth"
for how curves are attached to the surface. When the ground
truth surface changed, the original curves have to be updated
as well. Deforming curves based on an animated surface will be
done with geometry nodes independent of the operator.
In the UI, the operator is currently exposed in curves sculpt mode
in the `Curves > Snap Curves to Surface` menu.
Differential Revision: https://developer.blender.org/D14515
|
|
Add "for_write" on function names that retrieve mutable data arrays.
Though this makes function names longer, it's likely worth it because
it allows more easily using the const functions in a non-const context,
and reduces cases of mistakenly retrieving with edit access.
In the long term, this situation might change more if we implement
attributes storage that is accessible directly on `CurvesGeometry`
without duplicating the attribute API on geometry components,
which is currently the rough plan.
Differential Revision: https://developer.blender.org/D14562
|
|
The last length value was not initialized, and all length values were
moved one position towards the front of each curve incorrectly.
Also fix an assert when a curve only had a single point.
|
|
These functions are very simple, but some of them were showing up in
in profiles for curves sculpt mode and various curve nodes. Making sure
they are inlined will allow avoiding the compiler to optimize this logic
much better.
Differential Revision: https://developer.blender.org/D14529
|
|
This commit ports the "Set Handle Positions" and "Set Hanle Type"
nodes to use the new curves data-block. The nodes become simpler
and likely much faster too, though they're usually not the bottleneck
anyway.
Most of the code is ported from `BezierSpline` directly. The majority
of the complexity comes from the interaction between different
automatically calculated handle types. In comparison `BezierSpline`,
the calculation of auto handles is done eagerly-- mostly because it's
simpler. Eventually lazy calculation might be good to add.
Differential Revision: https://developer.blender.org/D14464
|