Commit Graph

827 Commits

Author SHA1 Message Date
98bee41c8a IO: Reversed persistent ID order in exports to Alembic and USD
Each duplicated (a.k.a. instanced) object has a Persistent ID, which
identifies a dupli within the context of its duplicator. This ID
consists of several numbers when there are nested duplis (for example a
mesh instancing empties on its vertices, where each empty instances a
collection). When exporting to Alembic/USD, these are used to uniquely
name the duplicated objects in the export.

This commit reverses the order of the persistent ID numbers, so that the
first number identifies the first level of recursion. This produces
trees like this:

    ABC
     `--Triangle
         |--Triangle
         |--Empty-1
         |    `--Pole-1-0
         |        |--Pole
         |        `--Block-1-1
         |            `--Block
         |--Empty
         |    `--Pole-0
         |        |--Pole
         |        `--Block-1
         |            `--Block
         |--Empty-2
         |    `--Pole-2-0
         |        |--Pole
         |        `--Block-2-1
         |            `--Block
         `--Empty-0
             `--Pole-0-0
                 |--Pole
                 `--Block-0-1
                     `--Block

It is now clearer that `Pole-2-0` and `Block-2-1` are instanced by
`Empty-2`. Before this commit, they would have been named `Pole-0-2` and
`Block-1-2`.
2020-07-07 14:30:55 +02:00
70b1c09d7a IO: Fix bug exporting dupli parent/child relations
Exporting a scene to USD or Alembic would fail when there are multiple
duplicates of parent & child objects, duplicated by the same object. For
example, this happens when such a hierarchy of objects is contained in a
collection, and that collection is instanced multiple times by mesh
vertices. The problem here is that the 'parent' pointer of each
duplicated object points to the real parent; Blender would not figure
out properly which duplicated parent should be used.

This is now resolved by keeping track of the persistent ID of each
duplicated instance, which makes it possible to reconstruct the
parent-child relations of duplicated objects. This does use up some
memory for each dupli, so it could be heavy to export a Spring scene
(with all the pebbles and leaves), but it's only a small addition on top
of the USD/Alembic writer objects that have to be created anyway. At
least with this patch, they're created correctly.

Code-wise, the following changes are made:

- The export graph (that maps export parent to its export children) used
  to have as its key (Object, Duplicator). This is insufficient to
  correctly distinguish between multiple duplis of the same object by
  the same duplicator, so this is now extended to (Object, Duplicator,
  Persistent ID). To make this possible, new classes `ObjectIdentifier`
  and `PersistentID` are introduced.
- Finding the parent of a duplicated object is done via its persistent
  ID. In Python notation, the code first tries to find the parent
  instance where `child_persistent_id[1:] == parent_persistent_id[1:]`.
  If that fails, the dupli with persistent ID `child_persistent_id[1:]`
  is used as parent.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D8233
2020-07-07 13:01:07 +02:00
955abbeff2 Fix sign conversion error 2020-07-07 09:01:01 +02:00
e20171e59f Fix build error with tests for removed functions
These GHash functions were removed in 12817083ec,
so the tests should be removed too.
2020-07-06 16:39:28 -04:00
f6f4043924 BLI: add methods to lookup a stored key in a set 2020-07-06 17:59:27 +02:00
572c48cf98 BLI: improve exception safety of memory utils
Even if we do not use exception in many places in Blender, our core C++ library
should become exception safe. Otherwise, we don't even have the option
to work with exceptions if we decide to do so.
2020-07-06 09:08:53 +02:00
703a73fa84 BLI: refactor how buffers for small object optimization are stored
Previously, there was an error when operator-> was returning an
invalid type. See error C2839.
2020-07-06 10:56:26 +02:00
247a28f242 Revert "BLI: refactor how buffers for small object optimization are stored"
This reverts commit 5d79f9f276.

This was introducing build errors in windows. Need a bit more time to check it.
2020-07-05 15:08:26 +02:00
5d79f9f276 BLI: refactor how buffers for small object optimization are stored 2020-07-05 16:30:26 +02:00
1e255ce031 Fix T72214: Fluids: noise does not work with negative frame numbers
The issue is duplicated code. There are two functions that zero-fill
the frame number. They worked the same for positive frames numbers, but
behaved differently for negative ones.

On frame `-100`, `BLI_path_frame` outputs `-0100` and
`fluid_cache_get_framenr_formatted_$ID$` outputted `-100`.

I changed the behavior of the latter, because we depend on the behavior
of the former for much longer already.

Reviewers: sebbas

Differential Revision: https://developer.blender.org/D8107
2020-07-03 15:27:02 +02:00
395b294b61 Cleanup: use nested namespaces 2020-07-03 14:25:20 +02:00
0949140d36 Fix compile error
This is the same issue as in rBbcf49d13e53454.
2020-06-30 18:32:38 +02:00
613f62d15c Functions: add two more customizable multi-functions 2020-06-30 18:18:48 +02:00
26cdab02a8 Cleanup: move tests into their corresponding namespace 2020-06-30 16:46:52 +02:00
37820651bb BLI: add Array constructor that does not initialize non-trivial types
This should rarely be necessary, but I have a use case coming up soon.
2020-06-30 15:58:29 +02:00
2917df21ad Alembic: new exporter based on the USD exporter structure
The Alembic exporter has been restructured by leverages the
`AbstractHierarchyIterator` introduced by the USD exporter. The produced
Alembic files have not changed much (details below), as the Alembic
writing code has simply been moved from the old exporter to the new. How
the export hierarchy is handled changed a lot, though, and also the way
in which transforms are computed. As a result, T71395 is fixed.

Differences between the old and new exporter, in terms of the produced
Alembic file:
- Duplicated objects now have a unique numerical suffix.
- Matrices are computed differently, namely by simply computing the
  evaluated transform of the object relative to the evaluated transform
  of its export-parent. This fixes {T71395}, but otherwise should
  produce the same result as before (but with simpler code).

Compared to the old Alembic exporter, Subdivision modifiers are now
disabled in a cleaner, more efficient way (they are disabled when
exporting with the "Apply Subdivisions" option is unchecked). Previously
the exporter would move to a new frame, disable the modifier, evaluate
the object, and enable the modifier again. This is now done before
exporting starts, and modifiers are only restored when exporting ends.

Some issues with the old Alembic exporter that have NOT been fixed in
this patch:
- Exporting NURBS patches and curves (see T49114 for example).
- Exporting flattened hierarchy in combination with dupli-objects. This
  seems to be broken in the old Alembic exporter as well, but nobody
  reported this yet.

Differential Revision: https://developer.blender.org/D7664

Reviewed By: Sergey
2020-06-30 11:38:46 +02:00
18bff53c99 BLI: remove blender::Optional in favor of std::optional
`std::optional` can be used now, because we switched to C++17.
2020-06-29 14:30:06 +02:00
ff82049642 Functions: add MutableAttributesRef data structure
This will be used to reference the content of a CustomData structure
in C++ code, that does not need to know who owns the data but only
works with it.
2020-06-27 20:58:35 +02:00
2350159101 Cleanup: make it easier to check if a CPPType is a specific compile time type 2020-06-27 13:28:46 +02:00
3a3708cefb Functions: Multi Function Network
A multi-function network is a graph data structure, where nodes are
multi-functions (or dummies) and links represent data flow.
New multi-functions can be derived from such a network. For that
one just has to specify two sets of sockets in the network that
represent the inputs and outputs of the new function.

It is possible to do optimizations like constant folding on this
data structure, but that is not implemented in this patch yet.

In a next step, user generated node trees are converted into a
MFNetwork, so that they can be evaluated efficiently for many particles.

This patch also includes some tests that cover the majority of the code.
However, this seems to be the kind of code that is best tested by some
.blend files. Building graph structures in code is possible, but is
not easy to understand afterwards.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D8049
2020-06-23 10:16:14 +02:00
c94a1f5349 Functions: add utilities that allow creating some multi-functions with less typing 2020-06-22 15:50:31 +02:00
6223385043 Functions: Various improvements to the spans and generic data structures
Most of this code is covered by unit tests.
2020-06-22 15:50:31 +02:00
1a448c66ed Cleanup: Alembic, move the C++ code to blender::io::alembic namespace
This commit only moves code into the `blender::io::alembic` namespace,
it does not move `static` functions into an anonymous namespace.

No functional changes.
2020-06-19 15:30:18 +02:00
89b7f785e6 Cleanup: Alembic, moved exporter code into separate directory
This moves most of the exporter-related code
from `source/blender/io/alembic/intern`
to   `source/blender/io/alembic/exporter`

This is to prepare the Alembic code for the switchover to using
`blender::io::AbstractHierarchyIterator`. When that happens, a few more
files will be added, and having things in a separate 'exporter'
directory makes things less cluttered.

Note that exporting consists of multiple steps (determine export
hierarchy, create Alembic archive, and then write data into it), which
is why the directory is called "exporter", but many of the files are
called "writer".

No functional changes.
2020-06-19 15:30:18 +02:00
2193e28dfc USD Test: Don't use designated initializers
This isn't really in C++ standard, some corner cases work in some
compilers (like when all fields are specified), but in general they
do not work.

For some reason MSVC builder started to complain about it now,
weird but better not rely on compiler specifics.
2020-06-19 12:36:37 +02:00
b3b445979e Tests: Use explicit signature constants
Are reported by MSVC 2019 after C++17 switch.

One might suggest lets just silence the warning, I will say why to have
specific signed/unsigned types in API just to then (usafely) ignore the
sign conversion.
2020-06-19 12:02:21 +02:00
0f78a57904 Make BLI_edgehash_test compatible with C++17
random_shuffle was removed (at least the used version).
2020-06-19 12:02:21 +02:00
2dff08c8ce Alembic: always export transforms as inheriting
Blender now always exports transforms as as "inheriting", as Blender has
no concept of parenting without inheriting the transform.

Previously only objects with an actual parent were marked as
"inheriting", and parentless objects as "non-inheriting". However,
certain packages (for example USD's Alembic plugin) are incompatible
with non-inheriting transforms and will completely ignore such
transforms, placing all such objects at the world origin.

When importing non-inheriting transforms from Alembic, Blender will
break the parent-child relation and thus force the child to (correctly)
interpret the transform as world matrix.
2020-06-19 10:24:57 +02:00
f106369ce8 Alembic: prevent spaces in names of exported particle systems
Other types already had spaces, periods, and colons replaced by
underscores. The upcoming Alembic exporter (based on the
`AbstractHierarcyIterator` class) will be more consistent and apply the
same naming rules everywhere. This is in preparation for that change.
The `get_…_name()` functions in `abc_util.{cc,h}` will be removed then.
2020-06-19 10:24:51 +02:00
0d744cf673 Alembic: export object data with object data name
Previously the Alembic exporter exported a mesh object to
`{object.name}/{object.name}Shape`. Now it exports to
`{object.name}/{mesh.name}` instead. The same change also applies to
other object data types.

Note that the code now is a bit hackish, as `m_name` is set even in
cases where it isn't used. This hackishness was already there, though,
but it's now just more visible. This will all be cleaned up when the
Alembic exporter is ported to use the `AbstractHierarchyImporter`
structure of the Universal Scene Description (USD) exporter.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D7672
2020-06-19 10:17:41 +02:00
69c3d9804f IO: Allow exporting a subset of the writers
This is in order to prepare for compatibility with the Alembic exporter.
That exporter is capable of writing object transforms and object data at
different (sub)frames.

The rename from `created_writers` to `used_writers` is necessary, as not
all created writers will be actually used in each iteration.

The Universal Scene Description (USD) exporter does not make use of
this.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D7670
2020-06-19 10:17:41 +02:00
084c5d6c7e IO: Move Abstract Hierarchy Iterator into io/common
The goal of the `AbstractHierarchyIterator` class (and supporting
classes) was to use it in different exporters. It shouldn't be part of
the USD module + namespace any more, now that it will also be used in
the upcoming Alembic exporter rewrite.

The source files are moved into `io/common`, which is compiled & linked
into a new library `bf_io_common`. The unittests are still inside the
`tests/gtests/usd` directory. They should be moved to a separate test
module too, but that will be delayed until after T73268 has been
resolved.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D7669
2020-06-19 10:17:41 +02:00
a5e176a8ed Allow interpolation of matrices with negative scale / axis flips
The matrix interpolation function `interp_m3_m3m3()` decomposes the
matrices into rotation and scale matrices, converts the rotation
matrices to quaternions, SLERPs the quaternions, and converts the result
back to a matrix. Since quaternions cannot represent axis flips, this
results in interpolation problems like described in T77154.

Our interpolation function is based on "Matrix Animation and Polar
Decomposition", by Ken Shoemake & Tom Duff. The paper states that it
produces invalid results when there is an axis flip in the rotation
matrix (or negative determinant, or negative scale, those all indicate
the same thing). Their solution is to multiply the rotation matrix with
`-I`, where `I` is the identity matrix. This is the same as element-wise
multiplication with `-1.0f`. My proposed solution is to not only do that
with the rotation matrix `R`, but also with the scale matrix `S`. This
ensures that the decomposition of `A = R * S` remains valid, while also
making it possible to conver the rotation component to a quaternion.

There is still an issue when interpolating between matrices with
different determinant. As the determinant represents the change in
volume when that matrix is applied to an object, interpolating between a
negative and a positive matrix will have to go through a zero
determinant. In this case the volume collapses to zero. I don't see this
as a big issue, though, as without this patch Blender would also produce
invalid results anyway.

Reviewed By: brecht, sergey

Differential Revision: https://developer.blender.org/D8048
2020-06-18 10:37:52 +02:00
46e4cdf788 Tests: added simple unittests for matrix interpolation
The interpolation of 4x4 and 3x3 matrices will fail when the rotation
component has a singularity, i.e. when there is one axis mirrored. Two
mirrored axes are just a rotation of 180 degrees around the third, and
three mirrored axes are such a rotation + a single axis mirror. To
prepare for a fix, I first wanted to cover the basic functionality with
a few unit tests.

These tests check that `interpolate(A, B, alpha)` always returns `A` for
`alpha=0`, always return `B` for `alpha=1`, and something in between for
`alpha=0.5`.
2020-06-18 10:37:46 +02:00
ad6cccf058 Refactor duplicate of data-blocks.
Main change from user side, besides that all pointers should now be
properly remapped to new IDs, is that linked objects are no longer
preserved when doing a full copy of scenes.

Will open a task to check whether we actually still want that behavior
(and re-code it in a more correct way then).

This is the main part of work done here, it aims at uniformizing and
sanitizing that 'deep copy' process for supported IDs (currently scenes,
collections and objects).

Note that there will be more follow up commits after that one, but this
should be the most risky and changing one.
2020-06-17 17:06:05 +02:00
4365de3870 Functions: Multi Function
This adds the `MultiFunction` type and some smallish utility types that it uses.
A `MultiFunction` encapsulates a function that is optimized for throughput by
always processing many elements at once.

This is an important part of the new particle system, because it allows us to
execute user generated node trees for many particles efficiently.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D8030
2020-06-16 16:35:57 +02:00
38c9573b23 BLI: fix Map.foreach_item method 2020-06-16 12:16:07 +02:00
9cc0597556 Functions: Wrap into blender namespace
Similar to previous commit, aims to resolve compilation on
devtoolset-6.
2020-06-12 15:39:16 +02:00
f8696742bb Fix/workaround compilation error on devtoolset-6
Smells like GCC bug [1], which is backed up by the fact that locally
GCC-10 and CLang-10 works fine.

Since the change is trivial (and, arguably, correct since there is
no real difference between tests code and actual code) seems fine to
fix.

Fix suggested by Jacques Lucke, thanks!

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480
2020-06-12 15:17:17 +02:00
3d18bd5c51 BLI: define default hash function for const types 2020-06-11 16:16:44 +02:00
f028760b83 BLI: make Map::Item and Map::MutableItem more accessible
This makes it easier to write range-for loops over all items
in the map without using auto.
2020-06-11 10:48:52 +02:00
474b288933 BLI: add Map.pop_default method
There is a nice use case for this in depsgraph code.

Also I added some previously missing calls to std::move.
2020-06-10 19:02:34 +02:00
4c172f7ca6 BLI: support constructing StringRef from start and end pointer 2020-06-10 18:27:18 +02:00
a58dc25b07 Cleanup: improve custom data type names
This is related to T76659.

This just renames data type names to `CD_PROP_STRING`, `CD_PROP_FLOAT`
and `CD_PROP_INT32`. It makes them a bit more specific and removes
unnecessary abbreviations.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D7980
2020-06-10 15:47:31 +02:00
4fefe3ac3b BLI: rename tests from "array_ref" to "span"
This was missing in an earlier commit.
2020-06-10 14:50:29 +02:00
a71f073dfb BLI: add Map.pop_try method
I found this pattern in depsgraph code more than once.
2020-06-10 14:47:22 +02:00
84a0a6d16c BLI: update behavior of Map.lookup_or_add
Previously, this function would expect a callback function as parameter.
This behavior is now in Map.lookup_or_add_cb. The new version just
takes the key and value directly.
2020-06-10 14:15:04 +02:00
f7c0f1b8b8 BLI: rename ArrayRef to Span
This also renames `MutableArrayRef` to `MutableSpan`.
The name "Span" works better, because `std::span` will provide
similar functionality in C++20. Furthermore, a shorter, more
concise name for a common data structure is nice.
2020-06-09 11:58:47 +02:00
9bb7d6ed68 BLI: put C++ data structures in "blender" namespace instead of "BLI"
We plan to use the "blender" namespace in other modules as well.
2020-06-09 10:27:24 +02:00
d8678e02ec BLI: generally improve C++ data structures
The main focus here was to improve the docs significantly. Furthermore,
I reimplemented `Set`, `Map` and `VectorSet`. They are now (usually)
faster, simpler and more customizable. I also rewrote `Stack` to make
it more efficient by avoiding unnecessary copies.

Thanks to everyone who helped with constructive feedback.

Approved by brecht and sybren.

Differential Revision: https://developer.blender.org/D7931
2020-06-09 10:15:43 +02:00