Age | Commit message (Collapse) | Author |
|
Requested in D16095 proposal - also USD & Alembic have import scale
option; OBJ has an export scale object but the import scale
was not there for some reason.
|
|
Previously "which material got assigned to an object in the end"
was not covered by tests. This is preparation for fixing T101685.
|
|
|
|
|
|
This makes it easier to pass more parameters to the iterator in the future.
Differential Revision: https://developer.blender.org/D16047
|
|
Use `verts` instead of `vertices` and `polys` instead of `polygons`
in the API added in 05952aa94d33eeb50. This aligns better with
existing naming where the shorter names are much more common.
|
|
For copy-on-write, we want to share attribute arrays between meshes
where possible. Mutable pointers like `Mesh.mvert` make that difficult
by making ownership vague. They also make code more complex by adding
redundancy.
The simplest solution is just removing them and retrieving layers from
`CustomData` as needed. Similar changes have already been applied to
curves and point clouds (e9f82d3dc7ee, 410a6efb747f). Removing use of
the pointers generally makes code more obvious and more reusable.
Mesh data is now accessed with a C++ API (`Mesh::edges()` or
`Mesh::edges_for_write()`), and a C API (`BKE_mesh_edges(mesh)`).
The CoW changes this commit makes possible are described in T95845
and T95842, and started in D14139 and D14140. The change also simplifies
the ongoing mesh struct-of-array refactors from T95965.
**RNA/Python Access Performance**
Theoretically, accessing mesh elements with the RNA API may become
slower, since the layer needs to be found on every random access.
However, overhead is already high enough that this doesn't make a
noticible differenc, and performance is actually improved in some
cases. Random access can be up to 10% faster, but other situations
might be a bit slower. Generally using `foreach_get/set` are the best
way to improve performance. See the differential revision for more
discussion about Python performance.
Cycles has been updated to use raw pointers and the internal Blender
mesh types, mostly because there is no sense in having this overhead
when it's already compiled with Blender. In my tests this roughly
halves the Cycles mesh creation time (0.19s to 0.10s for a 1 million
face grid).
Differential Revision: https://developer.blender.org/D15488
|
|
When allocating new `CustomData` layers, often we do redundant
initialization of arrays. For example, it's common that values are
allocated, set to their default value, and then set to some other
value. This is wasteful, and it negates the benefits of optimizations
to the allocator like D15082. There are two reasons for this. The
first is array-of-structs storage that makes it annoying to initialize
values manually, and the second is confusing options in the Custom Data
API. This patch addresses the latter.
The `CustomData` "alloc type" options are rearranged. Now, besides
the options that use existing layers, there are two remaining:
* `CD_SET_DEFAULT` sets the default value.
* Usually zeroes, but for colors this is white (how it was before).
* Should be used when you add the layer but don't set all values.
* `CD_CONSTRUCT` refers to the "default construct" C++ term.
* Only necessary or defined for non-trivial types like vertex groups.
* Doesn't do anything for trivial types like `int` or `float3`.
* Should be used every other time, when all values will be set.
The attribute API's `AttributeInit` types are updated as well.
To update code, replace `CD_CALLOC` with `CD_SET_DEFAULT` and
`CD_DEFAULT` with `CD_CONSTRUCT`. This doesn't cause any functional
changes yet. Follow-up commits will change to avoid initializing
new layers where the correctness is clear.
Differential Revision: https://developer.blender.org/D15617
|
|
|
|
While fixing T100302 (rBd76583cb4a1) I did not realize that the
change in imported vertex order would actually matter. Turns out, it
does for morph targets / mesh shape keys. So redo the fix in a way
that does not change the vertex order. Fixes T100421.
|
|
Implemented the same way as STL or GPencil SVG importers: loop over
the input files, import one by one.
Has been requested by the community for quite a long time
(e.g. https://blender.community/c/rightclickselect/Jhbbbc/), as well
as 3rd party addons to implement just this
(https://github.com/p2or/blender-batch-import-wavefront-obj).
|
|
textures are present
Report T98781 and part of T97642: the MTLMaterial info only captures
image nodes and the default socket values. When the image information
is present, do not emit the socket defaults - the .MTL spec states
they are multiplied together, but the default value is not used
in blender when the socket is connected.
Also contains svn tests repository update to extend the test coverage,
and update test expectation outputs.
|
|
span a continuous range
As part of the previous fix (D15410), the importer got code to track
min & max vertex indices used as part of the mesh faces. However, if
faces refer to a "sparse" (i.e. non-contiguous) subset of all vertices,
then the imported mesh would contain all the vertices between min & max
range.
Replace that with proper tracking of actually used vertex indices
for each imported mesh. Fixes T100302.
This does affect import performance a tiny bit, e.g. importing Blender
3.0 splash scene goes 21.7s -> 22.1s, and importing rungholt.obj
goes 2.37s -> 2.48s.
Importer related tests have a bunch of vertex changes in them, since
now vertices are added in the order that the faces are referring
to them. Which incidentally matches the order that the Python based
importer was creating them too.
|
|
The Python based exporter was replacing spaces with underscores
in object/group names, mostly to handle cases where names could begin
or end with spaces. The new exporter was not doing that. Note: spaces
in material names were already handled by the new exporter.
Fixes T97769. Updated test coverage expectations; one of the test
files has an object with a space in the name.
|
|
Python based OBJ importer, as well as glTF2 importer, are creating
"placeholder" images for texture images that can't be found. These
are empty textures (displayed as magenta), but with their file paths
set so that File > External Data > Report Missing Files can report
them as missing.
Make the new C++ OBJ importer do the same as well. Fixes T99502.
|
|
The Python based importer had logic to immediately turn image paths
into relative-to-blender-file paths, if user preference for relative
paths is used (which is on by default). The new importer code did not
have that. Fixes T100076.
|
|
The new OBJ/MTL importer was creating a new image for any referenced
texture, even if another material (or another property of the same
material) already referenced the same texture. Make it use
BKE_image_load_exists function just like Collada or USD importers do.
Fixes T100075. Extended test coverage to count imported images;
without the fix import_cubes_with_textures_rel would have incorrectly
created 5 images instead of 4.
|
|
any face
The Python based importer had a special case handling of "no faces in
the whole file at all", where it ended up treating the whole file
as essentially a point-cloud-like object (just loose vertices, no
faces or edges). The new importer code was missing this special case.
Fixes T100017. Added gtest coverage that was failing without the fix.
|
|
objects by name
Previously, when creating "very large" (tens-hundreds of thousands)
amounts of objects, the Blender code that was ensuring name
uniqueness was the bottleneck. That got recently addressed (D14162),
however now sorting of IDs by their names is the remaining bottleneck.
Name sorting code in Blender is optimized for the pattern where names
are inserted in already sorted order (i.e. objects expect to get added
near the end of the list). By doing this pre-sorting of objects
intended to get created by an importer (USD and OBJ, in this patch),
this sorting bottleneck can be largely removed, especially with very
high object counts.
Windows, Ryzen 5950X, import times:
- OBJ, splash screen scene (26k objects): 22.0s -> 20.7s
- USD, Disney Moana scene (250k objects): 585s -> 82.2s (10 minutes -> 1.5 minutes)
Reviewed By: Michael Kowalski, Howard Trickey
Differential Revision: https://developer.blender.org/D15506
|
|
The importer code was written under incorrect assumption that vertex
data (v, vn, vt commands etc.) are grouped by object, i.e. follow the
o command, and that each object has its own vertex data commands. This
is not the case -- all the vertex data in the whole OBJ file is
"global", with no relation to any objects/groups; it's just that the
faces belong to the object, and then they pull in any vertices they
like.
This patch fixes this incorrect assumption in the importer:
- Vertex data is now properly global; no need to track some sort of
"offsets" per object like it was doing before.
- For each object, face definitions track the minimum & maximum vertex
indices referenced by the object, and then all that vertex range is
created in the final Blender object. Note: it might be (unusual, but
possible) that an object does not reference a sequential range of
vertices, e.g. just a single face with vertex indices 1, 10, 100 --
the resulting Blender mesh will have all the 100 vertices (some
"loose" without belonging to a face). It should be possible to track
the used vertices exactly (e.g. with a vector set), but I haven't
done that for performance reasons.
Reviewed By: Howard Trickey
Differential Revision: https://developer.blender.org/D15410
|
|
The old Python OBJ importer had a (somewhat confusingly named) "Keep
Vertex Order -> Poly Groups" option, that imported OBJ groups as
"vertex groups" on the resulting mesh. All vertices of any face were
assigned the vertex group, with a 1.0 weight.
The new C++ importer did not have this option. It was trying to do
something with vertex groups, but failing to actually achieve
anything :) -- the vertex groups were created on the wrong object
(later on overwritten by "nomain mesh to main mesh" operation);
vertex weights were set to 1.0/vertex_count, and each vertex was only
set to be in one group, even when it belongs to multiple faces from
different groups. End result was that to the user, vertex groups were
not visible/present at all (see T98874).
This patch adds the import option (named "Vertex Groups"), which is
off by default, and fixes the import code logic to actually do the
right thing. Tested on file from T98874; vertex groups are imported
just like with the Python importer.
Reviewed By: Howard Trickey
Differential Revision: https://developer.blender.org/D15200
|
|
OBJ vertex color related tests were not producing identical results
across various platforms, primarily due to sRGB<->Linear color space
conversions.
While D15193 has just made the color space conversion accuracy match
much closer between platforms, it's still not 100% the same.
This change reduces the amount of decimal places used for exporting
vertex colors, to 4 digits (down from 6). Vertex normals were
already always printed with 4 digits, and colors are conceptually
similar (usually 0..1 range etc.).
This makes the vertex color tests pass again, so re-enable them
after adjusting to 4 decimals expectations.
|
|
platforms
|
|
Adds support for vertex colors to OBJ I/O.
Importer:
- Supports both "xyzrgb" and "MRGB" vertex color formats.
- Whenever vertex color is present in the file for a model, it is
imported and a Color attribute is created (per-vertex, full float
color data type). Color coming from the file is assumed to be sRGB,
and is converted to linear upon import.
Exporter:
- Option to export the vertex colors. Defaults to "off", since not
all 3rd party software supports vertex colors.
- When the option is "on", if a mesh has a color attribute layer,
the active one is exported in "xyzrgb" form. If the mesh has
per-face-corner colors, they are averaged on the vertices.
Colors are converted from linear to sRGB upon export.
Reviewed By: Howard Trickey
Differential Revision: https://developer.blender.org/D15159
|
|
|
|
To match the existing Python .obj importer, and to make it easier for
the user to determine which object is which, use the filename for the
default object name instead of "New object".
Differential Revision: https://developer.blender.org/D15133
|
|
A new experimentatl STL importer, written in C++. Roughly 7-9x faster than the
Python based one.
Reviewed By: Aras Pranckevicius, Hans Goudey.
Differential Revision: https://developer.blender.org/D14941
|
|
Also add missing task-ID reference & remove colon after \note as it
doesn't render properly in doxygen.
|
|
Continued improvements to the new C++ based OBJ importer.
Performance: about 2x faster.
- Rungholt.obj (several meshes, 263MB file): Windows 12.7s -> 5.9s, Mac 7.7s -> 3.1s.
- Blender 3.0 splash (24k meshes, 2.4GB file): Windows 97.3s -> 53.6s, Mac 137.3s -> 80.0s.
- "Windows" is VS2022, AMD Ryzen 5950X (32 threads), "Mac" is Xcode/clang 13, M1Max (10 threads).
- Slightly reduced memory usage during import as well.
The performance gains are a combination of several things:
- Replacing `std::stof` / `std::stoi` with C++17 `from_chars`.
- Stop reading input file char-by-char using `std::getline`, and instead read in 64kb chunks, and parse from there (taking care of possibly handling lines split mid-way due to chunk boundaries).
- Removing abstractions for splitting a line by some char,
- Avoid tiny memory allocations: instead of storing a vector of polygon corners in each face, store all the corners in one big array, and per-face only store indices "where do corners start, and how many". Likewise, don't store full string names of material/group names for each face; only store indices into overall material/group names arrays.
- Stop always doing mesh validation, which is slow. Do it just like the Alembic importer does: only do validation if found some invalid faces during import, or if requested by the user via an import setting checkbox (which defaults to off).
- Stop doing "collection sync" for each object being added; instead do the collection sync right after creating all the objects.
Cleanup / Robustness:
This reworking of parser (see "removing abstractions" point above) means that all the functions that were in `parser_string_utils` file are gone, and replaced with different set of functions. However they are not OBJ specific, so as pointed out during review of the previous differential, they are now in `source/blender/io/common` library.
Added gtest coverage for said functions as well; something that was only indirectly covered by obj tests previously.
Rework of some bits of parsing made the parser actually better able to deal with invalid syntax. E.g. previously, if a face corner were a `/123` string, it would have incorrectly treated that as a vertex index (since it would get "hey that's one number" after splitting a string by a slash), instead of properly marking it as invalid syntax.
Added gtest coverage for .mtl parsing; something that was not covered by any tests at all previously.
Reviewed By: Howard Trickey
Differential Revision: https://developer.blender.org/D14586
|
|
multiple curve types
- Was not exporting "Poly" curves at all,
- Had a crash when a single object contains multiple curves of different types -- it had a check for "is this nurbs compatible?" only for the first curve, and then proceeded to treat the other curves as nurbs as well, without checking for validity.
Fixed both issues by doing the same logic as in the old python exporter:
- Poly curves are supported,
- Treat object as "nurbs compatible" only if all the curves within it are nurbs compatible.
Added test coverage in the gtest suite. While at it, made "all_curves" test use the "golden obj file template" style test, instead of a manually coded test that checks intermediate objects but does not check the final exported result.
Reviewed By: Howard Trickey
Differential Revision: https://developer.blender.org/D14611
|
|
print obj failure output diff details
The all_objects.blend test scene (in subversion tests repo) contained an
object with a subdivision surface. Which changes vertex positions
slightly, depending on used OpenSubDiv version and the compile flags. It
seems that the intent of the test was "test export of meshes that use
modifiers", so I changed that object to be a cube with a simple "taper"
modifier instead.
While at it, changed OBJ exporter test code to always print the
"expected and what we got" text difference details, when a test fails.
Much easier to see than just "the files are different" output. The code
to print that was behind an off by default flag for some reason.
This diff should get comitted together with updated all_objects templates
in subversion tests repo.
Reviewed By: Sebastian Parborg
Differential Revision: https://developer.blender.org/D14597
|
|
This commit furthers some of the changes that were started in
rBb9febb54a492 and subsequent commits by changing the way surface
objects are presented to render engines and other users of evaluated
objects in the same way. Instead of presenting evaluated surface objects
as an `OB_SURF` object with an evaluated mesh, `OB_SURF` objects
can now have an evaluated geometry set, which uses the same system
as other object types to deal with multi-type evaluated data.
This clarification makes it more obvious that lots of code that dealt
with the `DispList` type isn't used. It wasn't before either, now it's
just *by design*. Over 1100 lines can be removed. The legacy curve
draw cache code is much simpler now too. The idea behind the further
removal of `DispList` is that it's better to focus optimization efforts
on a single mesh data structure.
One expected functional change is that the evaluated mesh from surface
objects can now be used in geometry nodes with the object info node.
Cycles and the OBJ IO tests had to be tweaked to avoid using evaluated
surface objects instead of the newly exposed mesh objects.
Differential Revision: https://developer.blender.org/D14550
|
|
Related to D13958
|
|
This takes state of soc-2020-io-performance branch as it was at
e9bbfd0c8c7 (2021 Oct 31), merges latest master (2022 Apr 4),
adds a bunch of tests, and fixes a bunch of stuff found by said
tests. The fixes are detailed in the differential.
Timings on my machine (Windows, VS2022 release build, AMD Ryzen
5950X 32 threads):
- Rungholt minecraft level (269MB file, 1 mesh): 54.2s -> 14.2s
(memory usage: 7.0GB -> 1.9GB).
- Blender 3.0 splash scene: "I waited for 90 minutes and gave up"
-> 109s. Now, this time is not great, but at least 20% of the
time is spent assigning unique names for the imported objects
(the scene has 24 thousand objects). This is not specific to obj
importer, but rather a general issue across blender overall.
Test suite file updates done in Subversion tests repository.
Reviewed By: @howardt, @sybren
Differential Revision: https://developer.blender.org/D13958
|