Commit Graph

158 Commits

Author SHA1 Message Date
Aras Pranckevicius
d3242b772b obj: improve placement of shader nodes in imported materials
Previously for most materials (especially the ones without any
textures), the nodes were "off screen" way to the right, requiring
a view framing to even see them.

Also, as soon as multiple images were used, many nodes overlapped
one another and the connections were all a mess.

Simplify all that, and now each node type (coordinate, mapping, image,
normal map, bsdf etc.) is in it's own column, with BSDF at zero
coordinate. Each used image (along with any possible coordinate,
mapping, normal map) is it's own row. The resulting connections
are much cleaner.
2022-09-02 21:03:44 +03:00
Aras Pranckevicius
9d59734ffd Fix build (missing include from fa40013009) 2022-09-01 21:57:42 +03:00
Aras Pranckevicius
fa40013009 Cleanup: obj: simplify material node tree creation
As pointed out in D15827 comment, the unique_ptr usage in
ShaderNodetreeWrap related code does not sound very useful. Looking at
it, whole ShaderNodetreeWrap does not make much sense - it's only
ever created, and then immediately just one thing is fetched from it.
This very much sounds like "a function", so make it just that -
header file contains just a `create_mtl_node_tree` function, and the
whole implementation is hidden from the users. Which I've also
simplified into just a handful of freestanding functions.

No functionality or performance changes, but the code does get ~80
lines shorter.
2022-09-01 21:26:28 +03:00
Aras Pranckevicius
08894ac929 Merge branch 'blender-v3.3-release' 2022-09-01 20:44:09 +03:00
Aras Pranckevicius
f366d197db Fix T100737: OBJ/USD import: imported object has no active material, material has 2 users
Fixes issues in importers written in C++ (T100737):

- Materials had one reference count too much. Affected Collada,
  Alembic, USD, OBJ importers, looks like "since forever".
- Active material index was not properly set on imported meshes.
  Regression since 3.3 (D15145). Affected Alembic, USD, OBJ. Note:
  now it sets the first material as the active one, whereas
  previously the last one was set as active. First one sounds more
  "intuitive" to me.

Reviewed By: Bastien Montagne
Differential Revision: https://developer.blender.org/D15831
2022-09-01 20:38:56 +03:00
Bastien Montagne
05fe7ca5af Merge branch 'blender-v3.3-release' 2022-09-01 12:43:13 +02:00
Bastien Montagne
414baf9780 Fix invalid memory handling in C++ OBJ MTL Importer.
An ID created with regualr ID management code should never ever be
directly freed directly.

For embedded nodetrees, there is a dedicated function.

Reviewed By: aras_p

Differential Revision: https://developer.blender.org/D15827
2022-09-01 09:17:02 +02:00
Hans Goudey
f1c0249f34 Mesh: Move material indices to a generic attribute
This patch moves material indices from the mesh `MPoly` struct to a
generic integer attribute. The builtin material index was already
exposed in geometry nodes, but this makes it a "proper" attribute
accessible with Python and visible in the "Attributes" panel.

The goals of the refactor are code simplification and memory and
performance improvements, mainly because the attribute doesn't have
to be stored and processed if there are no materials. However, until
4.0, material indices will still be read and written in the old
format, meaning there may be a temporary increase in memory usage.

Further notes:
* Completely removing the `MPoly.mat_nr` after 4.0 may require
  changes to DNA or introducing a new `MPoly` type.
* Geometry nodes regression tests didn't look at material indices,
  so the change reveals a bug in the realize instances node that I fixed.
* Access to material indices from the RNA `MeshPolygon` type is slower
  with this patch. The `material_index` attribute can be used instead.
* Cycles is changed to read from the attribute instead.
* BMesh isn't changed in this patch. Theoretically it could be though,
  to save 2 bytes per face when less than two materials are used.
* Eventually we could use a 16 bit integer attribute type instead.

Ref T95967

Differential Revision: https://developer.blender.org/D15675
2022-08-31 09:09:01 -05:00
Jacques Lucke
25e307d725 Nodes: move NodeTreeRef functionality into node runtime data
The purpose of `NodeTreeRef` was to speed up various queries on a read-only
`bNodeTree`. Not that we have runtime data in nodes and sockets, we can also
store the result of some queries there. This has some benefits:
* No need for a read-only separate node tree data structure which increased
  complexity.
* Makes it easier to reuse cached queries in more parts of Blender that can
  benefit from it.

A downside is that we loose some type safety that we got by having different
types for input and output sockets, as well as internal and non-internal links.

This patch also refactors `DerivedNodeTree` so that it does not use
`NodeTreeRef` anymore, but uses `bNodeTree` directly instead.

To provide a convenient API (that is also close to what `NodeTreeRef` has), a
new approach is implemented: `bNodeTree`, `bNode`, `bNodeSocket` and `bNodeLink`
now have C++ methods declared in `DNA_node_types.h` which are implemented in
`BKE_node_runtime.hh`. To make this work, `makesdna` now skips c++ sections when
parsing dna header files.

No user visible changes are expected.

Differential Revision: https://developer.blender.org/D15491
2022-08-31 12:16:13 +02:00
Aras Pranckevicius
68f234b8ab Cleanup: obj: simplify import/export syntax handling code
I want to add support for PBR materials extension to OBJ, but the way
current I/O code syntax handling was done made it quite cumbersome
to extend the number of MTL textures/parameters.

Simplify all that by removing FormatHandler template on "syntax"
that gets routed through keyword enums, and instead just have
simple `write_obj_*` and `write_mtl_*` functions.

Simplify MTLMaterial to not contain a map of textures (that is always
fully filled with all possible textures), instead now there's
a simple array. Rename `tex_map_XX` to `MTLTexMap`.

All this does not affect behavior or performance, but it does result
in 170 fewer lines of code, and saves a couple kilobytes of executable
size.
2022-08-31 11:18:34 +03:00
Hans Goudey
25237d2625 Attributes: Improve custom data initialization options
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
2022-08-30 14:56:05 -05:00
Hans Goudey
6577d2df8c Cleanup: Use const for custom data layers 2022-08-29 17:00:46 -05:00
Campbell Barton
28750bcf7e Cleanup: replace NULL with nullptr for C++ files 2022-08-28 20:52:28 +10:00
Campbell Barton
4fb64068a7 Cleanup: use determinant_m3(m) < 0 to implement is_negative_m3/m4
Use a more direct method of checking if a matrix is negative instead of
using cross & dot product.

Also replace some determinant_m3() < 0 checks with is_negative_m3.
2022-08-24 16:34:04 +10:00
Richard Antalik
a77a1bcae7 Merge branch 'blender-v3.3-release' 2022-08-23 15:09:50 +02:00
Campbell Barton
ffb6cc263f Cleanup: format 2022-08-23 22:55:48 +10:00
Philipp Oeser
13b2716e1c Merge branch 'blender-v3.3-release' 2022-08-23 14:25:18 +02:00
Philipp Oeser
65870821da Fix: OBJ import unused parameter warning
Since {rB2542fda14d85}, `r_node` is an unused parameter.
Changed `load_texture_image` to reflect that.

Differential Revision: https://developer.blender.org/D15759
2022-08-23 14:22:23 +02:00
Hans Goudey
27f2ff6b5b Cleanup: Remove redundant use of evaluated non-mesh objects
Metaball, curve, text, and surface objects use the geometry component
system to add evaluated mesh object instances to the dependency graph
"for render engine" iterator. Therefore it is unnecessary to process
those object types in these loops-- it would either be redundant work
or a no-op.
2022-08-17 13:02:45 -04:00
Hans Goudey
eaa87101cd Metaball: Evaluate metaball objects as mesh components
With the ultimate goal of simplifying drawing and evaluation,
this patch makes the following changes and removes code:
- Use `Mesh` instead of `DispList` for evaluated basis metaballs.
- Remove all `DispList` drawing code, which is now unused.
- Simplify code that converts evaluated metaballs to meshes.
- Store the evaluated mesh in the evaluated geometry set.

This has the following indirect benefits:
- Evaluated meshes from metaball objects can be used in geometry nodes.
- Renderers can ignore evaluated metaball objects completely
- Cycles rendering no longer has to convert to mesh from `DispList`.
- We get closer to removing `DispList` completely.
- Optimizations to mesh rendering will also apply to metaball objects.

The vertex normals on the evaluated mesh are technically invalid;
the regular calculation wouldn't reproduce them. Metaball objects
don't support modifiers though, so it shouldn't be a problem.
Eventually we can support per-vertex custom normals (T93551).

Differential Revision: https://developer.blender.org/D14593
2022-08-17 10:20:25 -04:00
Aras Pranckevicius
1221a4049c Merge branch 'blender-v3.3-release' 2022-08-16 13:50:19 +03:00
Aras Pranckevicius
efdcef7855 Fix T100421: OBJ importer in 3.3 does not keep the vertex order
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.
2022-08-16 13:49:37 +03:00
Hans Goudey
2480b55f21 Mesh: Move hide flags to generic attributes
This commit moves the hide status of mesh vertices, edges, and faces
from the `ME_FLAG` to optional generic boolean attributes. Storing this
data as generic attributes can significantly simplify and improve code,
as described in T95965.

The attributes are called `.hide_vert`, `.hide_edge`, and `.hide_poly`,
using the attribute name semantics discussed in T97452. The `.` prefix
means they are "UI attributes", so they still contain original data
edited by users, but they aren't meant to be accessed procedurally by
the user in arbitrary situations. They are also be hidden in the
spreadsheet and the attribute list by default,

Until 4.0, the attributes are still written to and read from the mesh
in the old way, so neither forward nor backward compatibility are
affected. This means memory requirements will be increased by one byte
per element when the hide status is used. When the flags are removed
completely, requirements will decrease when hiding is unused.

Further notes:
 * Some code can be further simplified to skip some processing when the
   hide attributes don't exist.
 * The data is still stored in flags for `BMesh`, necessitating some
   complexity in the conversion to and from `Mesh`.
 * Access to the "hide" property of mesh elements in RNA is slower.
   The separate boolean arrays should be used where possible.

Ref T95965

Differential Revision: https://developer.blender.org/D14685
2022-08-11 12:59:06 -04:00
Aras Pranckevicius
4cbd799373 obj: support importing multiple files at once
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).
2022-08-11 17:05:54 +03:00
Aras Pranckevicius
c4a0438522 Merge branch 'blender-v3.3-release' 2022-08-11 15:54:04 +03:00
Aras Pranckevicius
0a096f2be2 Fix T98781: OBJ exporter wrongly writing default material socket values when 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.
2022-08-11 15:51:36 +03:00
Aras Pranckevicius
bb3174e15b Merge branch 'blender-v3.3-release' 2022-08-10 18:06:13 +03:00
Aras Pranckevicius
8c59b93505 obj: Also find .mtl images by their basename, if all else fails (T77801)
While T77801 itself is working as expected in the new C++ obj
importer, the repro file there uses absolute paths to material images,
yet the images themselves are right there in the current folder.

The old python based importer did find them, since it was doing a
really complex image search. My understanding is that while C++
importer was developed, it was decided to not do that -- however
just the "basename file in the mtl directory" sounds simple enough
and gets the repro case file work correctly.
2022-08-10 18:03:39 +03:00
Aras Pranckevicius
089216067f Merge branch 'blender-v3.3-release' 2022-08-10 13:36:48 +03:00
Aras Pranckevicius
d76583cb4a Fix T100302: New OBJ importer produces too many vertices when faces don't 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.
2022-08-10 13:34:58 +03:00
Hans Goudey
bc15812e0d Merge branch 'blender-v3.3-release' 2022-08-03 17:03:16 -05:00
Hans Goudey
1cc11e32e4 Fix: Avoid OBJ importer assert seting normals on mesh with no faces 2022-08-03 16:59:03 -05:00
Aras Pranckevicius
e3913ec6c1 Merge branch 'blender-v3.3-release' 2022-08-03 09:51:34 +03:00
Aras Pranckevicius
89f0fedb5c Fix T97769: new OBJ exporter does not replace spaces in object names
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.
2022-08-03 09:49:56 +03:00
Hans Goudey
dadfdc8226 Merge branch 'blender-v3.3-release' 2022-08-02 09:51:08 -05:00
Hans Goudey
d3eef4d22a Fix: Use evaluated materials in OBJ exporter
Since 1a81d268a1, materials on object data can change during
evaluation. But a different function is necessary to retrieve materials
taking that into account.

Solves part of T96721.

Differential Revision: https://developer.blender.org/D15595
2022-08-02 09:49:51 -05:00
Aras Pranckevicius
6b6d3b86d5 Merge branch 'blender-v3.3-release' 2022-08-01 21:19:27 +03:00
Aras Pranckevicius
2542fda14d Fix T99502: OBJ/MTL import: behavior changed for missing texture files
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.
2022-08-01 21:14:14 +03:00
Aras Pranckevicius
0adedaa4cc Merge branch 'blender-v3.3-release' 2022-08-01 13:39:59 +03:00
Aras Pranckevicius
e2be6bc03f Fix T100076: OBJ import: new importer doesn't use //relative/image/paths
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.
2022-08-01 13:39:08 +03:00
Aras Pranckevicius
5b1ad3d7cf Merge branch 'blender-v3.3-release' 2022-07-31 18:32:26 +03:00
Aras Pranckevicius
bea5281919 Fix T100075: OBJ import: images loaded multiple times instead of being reused
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.
2022-07-31 18:10:48 +03:00
Aras Pranckevicius
d31886b3fe Cleanup: braces around statements in OBJ parser 2022-07-30 13:10:35 +03:00
Aras Pranckevicius
c49717a824 Fix T100017: OBJ: new importer does not import vertices that aren't part of 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.
2022-07-28 16:39:42 +03:00
Aras Pranckevicius
092732d113 IO: speed up import of large amounts of objects in USD/OBJ by pre-sorting 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
2022-07-23 15:16:14 +03:00
Campbell Barton
d4a4691c0c Cleanup: spelling in comments 2022-07-11 10:38:04 +10:00
Aras Pranckevicius
fad857f473 Fix T99532: New OBJ importer in some cases fails to import faces
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
2022-07-10 20:09:29 +03:00
Aras Pranckevicius
4114ace616 Fix T99536: new 3.2 OBJ importer fails with trailing space after wrapped lines
Address the issue by re-working line continuation handling: stop
trying to parse sequences like "backslash, newline" (which is the
bug: it should also handle "backslash, possible whitespace, newline")
during parsing. Instead, fixup line continuations after reading chunks
of input file data - turn backslash and the following newline into
spaces. The rest of parsing code does not have to be aware of them
at all then.

Makes the file attached to T99536 load correctly now. Also will extend
one of the test files in subversion tests repo to contain backslashes
followed by newlines.
2022-07-10 18:27:38 +03:00
Jacques Lucke
b876ce2a4a Geometry Nodes: new geometry attribute API
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
2022-07-08 16:16:56 +02:00
Aras Pranckevicius
50f9c1c09c OBJ: more robust .mtl texture offset/scale parsing (T89421)
As pointed out in a comment on T89421, if a MTL file contained
something like: `map_Ka -o 1 2.png` then it was parsed as having
offset `1 2` and the texture filename just a `.png`. Make it so that
mtl option numbers are parsed in a way where the number is only
accepted only if it's followed by whitespace.

Differential Revision: https://developer.blender.org/D15385
2022-07-07 11:34:13 +03:00