Commit Graph

211 Commits

Author SHA1 Message Date
b599820418 OBJ: add split by objects/groups import options (T103839)
The new C++ OBJ importer was missing "split by objects" / "split by
groups" import settings of the older Python importer.
Implements T103839.

Added test coverage for all 4 possible combinations of these two
options.
2023-01-12 22:47:39 +02:00
dd9e1eded0 Mesh: Move sharp edge flag to generic attribute
Move the `ME_SHARP` flag for mesh edges to a generic boolean
attribute. This will help allow changing mesh edges to just a pair
of integers, giving performance improvements. In the future it could
also give benefits for normal calculation, which could more easily
check if all or no edges are marked sharp, which is helpful considering
the plans in T93551.

The attribute is generally only allocated when it's necessary. When
leaving edit mode, it will only be created if an edge is marked sharp.
The data can be edited with geometry nodes just like a regular edge
domain boolean attribute.

The attribute is named `sharp_edge`, aiming to reflect the similar
`select_edge` naming and to allow a future `sharp_face` name in
a separate commit.

Ref T95966

Differential Revision: https://developer.blender.org/D16921
2023-01-10 16:12:14 -05:00
Martijn Versteegh
6c774feba2 Mesh: Move UV layers to generic attributes
Currently the `MLoopUV` struct stores UV coordinates and flags related
to editing UV maps in the UV editor. This patch changes the coordinates
to use the generic 2D vector type, and moves the flags into three
separate boolean attributes. This follows the design in T95965, with
the ultimate intention of simplifying code and improving performance.

Importantly, the change allows exporters and renderers to use UVs
"touched" by geometry nodes, which only creates generic attributes.
It also allows geometry nodes to create "proper" UV maps from scratch,
though only with the Store Named Attribute node for now.

The new design considers any 2D vector attribute on the corner domain
to be a UV map. In the future, they might be distinguished from regular
2D vectors with attribute metadata, which may be helpful because they
are often interpolated differently.

Most of the code changes deal with passing around UV BMesh custom data
offsets and tracking the boolean "sublayers". The boolean layers are
use the following prefixes for attribute names: vert selection: `.vs.`,
edge selection: `.es.`, pinning: `.pn.`. Currently these are short to
avoid using up the maximum length of attribute names. To accommodate
for these 4 extra characters, the name length limit is enlarged to 68
bytes, while the maximum user settable name length is still 64 bytes.

Unfortunately Python/RNA API access to the UV flag data becomes slower.
Accessing the boolean layers directly is be better for performance in
general.

Like the other mesh SoA refactors, backward and forward compatibility
aren't affected, and won't be changed until 4.0. We pay for that by
making mesh reading and writing more expensive with conversions.

Resolves T85962

Differential Revision: https://developer.blender.org/D14365
2023-01-10 01:01:43 -05:00
1af62cb3bf Mesh: Move positions to a generic attribute
**Changes**
As described in T93602, this patch removes all use of the `MVert`
struct, replacing it with a generic named attribute with the name
`"position"`, consistent with other geometry types.

Variable names have been changed from `verts` to `positions`, to align
with the attribute name and the more generic design (positions are not
vertices, they are just an attribute stored on the point domain).

This change is made possible by previous commits that moved all other
data out of `MVert` to runtime data or other generic attributes. What
remains is mostly a simple type change. Though, the type still shows up
859 times, so the patch is quite large.

One compromise is that now `CD_MASK_BAREMESH` now contains
`CD_PROP_FLOAT3`. With the general move towards generic attributes
over custom data types, we are removing use of these type masks anyway.

**Benefits**
The most obvious benefit is reduced memory usage and the benefits
that brings in memory-bound situations. `float3` is only 3 bytes, in
comparison to `MVert` which was 4. When there are millions of vertices
this starts to matter more.

The other benefits come from using a more generic type. Instead of
writing algorithms specifically for `MVert`, code can just use arrays
of vectors. This will allow eliminating many temporary arrays or
wrappers used to extract positions.

Many possible improvements aren't implemented in this patch, though
I did switch simplify or remove the process of creating temporary
position arrays in a few places.

The design clarity that "positions are just another attribute" brings
allows removing explicit copying of vertices in some procedural
operations-- they are just processed like most other attributes.

**Performance**
This touches so many areas that it's hard to benchmark exhaustively,
but I observed some areas as examples.
* The mesh line node with 4 million count was 1.5x (8ms to 12ms) faster.
* The Spring splash screen went from ~4.3 to ~4.5 fps.
* The subdivision surface modifier/node was slightly faster
RNA access through Python may be slightly slower, since now we need
a name lookup instead of just a custom data type lookup for each index.

**Future Improvements**
* Remove uses of "vert_coords" functions:
  * `BKE_mesh_vert_coords_alloc`
  * `BKE_mesh_vert_coords_get`
  * `BKE_mesh_vert_coords_apply{_with_mat4}`
* Remove more hidden copying of positions
* General simplification now possible in many areas
* Convert more code to C++ to use `float3` instead of `float[3]`
  * Currently `reinterpret_cast` is used for those C-API functions

Differential Revision: https://developer.blender.org/D15982
2023-01-10 00:10:43 -05:00
8f44c37f5c Cleanup: Rename BLI_math_vec_types* files to BLI_math_vector_types
This is for the sake of consistency and clarity.
2023-01-06 20:09:51 +01:00
da4e2fe7fe OBJ: in exporter faces loop, move material index accessor outside of the loop
While the cost of creating AttributeAccessor and finding the "material_index"
attribute is not large, there's really no need to do that for each
polygon. Move the access outside of the per-polygon loop.
2023-01-02 16:15:34 +02:00
eaef8d50bc Fix T102672: OBJ exporter "material groups" option wrong for objects with >32k faces
Turns out, using the wrong output buffer (global one, instead of
per-thread one) puts the data into the wrong buffer! Fixes T102672
2023-01-02 16:15:34 +02:00
3277879085 Fix T103441: make OBJ importer ignore any unrecognized trailing per-face index data.
Some files out there (e.g. in T103441) contain face definitions with
four indices, which the importer code was not expecting. The OBJ
standard spells out up to three indices per face corner; the file in
there must be using some sort of non-standard OBJ syntax extension.
Now the code simply ignores any trailing per-face-corner data.
2023-01-01 19:30:20 +02:00
8007f7e74f Fix T103212: ignore OBJ UV indices if no UVs are present
Similar to T98782 that was about normal indices: some files out there
are technically "wrong" since they refer to UV indices, without ever
defining any UVs. If the file does not have any UVs, simply ignore UV
indices in the OBJ face definitions. Fixes T103212.
2023-01-01 19:14:37 +02:00
b492dc3579 Cleanup: Remove unused modifier and BMesh includes 2022-12-21 13:10:51 -06:00
6514bb05ea Mesh: Store active & default color attributes with strings
Attributes are unifying around a name-based API, and we would like to
be able to move away from CustomData in the future. This patch moves
the identification of active and fallback (render) color attributes
to strings on the mesh from flags on CustomDataLayer. This also
removes some ugliness used to retrieve these attributes and maintain
the active status.

The design is described more here: T98366

The patch keeps forward compatibility working until 4.0 with
the same method as the mesh struct of array refactors (T95965).

The strings are allowed to not correspond to an attribute, to allow
setting the active/default attribute independently of actually filling
its data. When applying a modifier, if the strings don't match an
attribute, they will be removed.

The realize instances / join node and join operator take the names from
the first / active input mesh. While other heuristics may be helpful
(and could be a future improvement), just using the first is simple
and predictable.

Differential Revision: https://developer.blender.org/D15169
2022-12-15 14:21:35 -06:00
bf1791ba92 BLI: add clear-and-shrink method to more data structures
Also renames the existing `clear_and_make_inline` to `clear_and_shrink`
which is more concise.
2022-12-09 12:00:37 +01:00
a5f9f7e2fc OBJ: Avoid retrieving mesh arrays, improve const correctness
Store the potentially owned mesh separately from the original/evaluated
mesh which is now stored with a const pointer. Also store mesh spans
separately in the class so they don't have to be retrieved for every
index.
2022-12-06 15:26:42 -06:00
2ce6ac462b Cleanup: Const correctness for node find functions
You shouldn't be able to retrieve a mutable node from a const node tree
or a mutable socket from a const node. Use const_cast in one place in
order to correct this without duplicating the function, which is still
awkward in the C-API.
2022-12-05 11:37:55 -06:00
507b724056 Cleanup: Remove unnecessary BMesh unique pointer in OBJ code
This is only used once, it's simpler to just free it in that case and
wait for further RAII improvements from elsewhere in the codebase.
2022-11-30 10:46:37 -06:00
0b13e7ce0f Cleanup: Remove unnecessary use of deprecated DNA define
This was solved by `dna::shallow_copy`
2022-11-30 10:27:33 -06:00
1ea169d90e Mesh: Move loose edge flag to a separate cache
As part of T95966, this patch moves loose edge information out of the
flag on each edge and into a new lazily calculated cache in mesh
runtime data. The number of loose edges is also cached, so further
processing can be skipped completely when there are no loose edges.

Previously the `ME_LOOSEEDGE` flag was updated on a "best effort"
basis. In order to be sure that it was correct, you had to be sure
to call `BKE_mesh_calc_edges_loose` first. Now the loose edge tag
is always correct. It also doesn't have to be calculated eagerly
in various places like the screw modifier where the complexity
wasn't worth the theoretical performance benefit.

The patch also adds a function to eagerly set the number of loose
edges to zero to avoid building the cache. This is used by various
primitive nodes, with the goal of improving drawing performance.
This results in a few ms shaved off extracting draw data for some
large meshes in my tests.

In the Python API, `MeshEdge.is_loose` is no longer editable.
No built-in addons set the value anyway. The upside is that
addons can be sure the data is correct based on the mesh.

**Tests**
There is one test failure in the Python OBJ exporter: `export_obj_cube`
that happens because of existing incorrect versioning. Opening the
file in master, all the edges were set to "loose", which is fixed
by this patch.

Differential Revision: https://developer.blender.org/D16504
2022-11-18 16:05:06 -06:00
455d195d55 OBJ Export: Remove edge recalculation
The removed function call removes all attributes from mesh edges
and rebuilds the mesh edge topology. This isn't necessary because
meshes always have edges in the first place.

Exporting a 4 million face grid, this saved 1.5 seconds out of 4
seconds total for the whole export.

Tests files have to be updated, since the edge calculation could
potentially change the order of elements. This is also a fix, since
previously the exporter would delete all attributes on the evaluated
mesh edges.

Differential Revision: https://developer.blender.org/D16391
2022-11-05 16:28:13 +01:00
e673f3ba24 Cleanup: Remove redundant assignment of loose edge flag
This is assigned by `BKE_mesh_calc_edges_loose` a few lines below.
2022-11-05 13:26:52 +01:00
23dafa4ad6 Cleanup: OBJ: Simplify access to loose edges
Implementing this with a separate function just added extra code,
there wasn't much benefit to it.
2022-11-04 21:58:15 +01:00
f17fbf8065 Refactor: Rename Object->obmat to Object->object_to_world
Motivation is to disambiguate on the naming level what the matrix
actually means. It is very easy to understand the meaning backwards,
especially since in Python the name goes the opposite way (it is
called `world_matrix` in the Python API).

It is important to disambiguate the naming without making developers
to look into the comment in the header file (which is also not super
clear either). Additionally, more clear naming facilitates the unit
verification (or, in this case, space validation) when reading an
expression.

This patch calls the matrix `object_to_world` which makes it clear
from the local code what is it exactly going on. This is only done
on DNA level, and a lot of local variables still follow the old
naming.

A DNA rename is setup in a way that there is no change on the file
level, so there should be no regressions at all.

The possibility is to add `_matrix` or `_mat` suffix to the name
to make it explicit that it is a matrix. Although, not sure if it
really helps the readability, or is it something redundant.

Differential Revision: https://developer.blender.org/D16328
2022-11-01 10:48:18 +01:00
89525fae59 Cleanup: CMake include paths
Remove redundant separators & redundant references to parent paths.
2022-10-19 21:37:10 +11:00
1d1cade9a9 BLI_path: remove trailing NULL argument to BLI_path_join
Using varargs had the disadvantages, replace with a macro which has
some advantages.

- Arguments are type checked.
- Less verbose.
- Unintended NULL arguments would silently terminate joining paths.
- Passing in a NULL argument warns with GCC.
2022-10-17 11:16:41 +11:00
499af28a35 IO: remove BKE_layer_collection_resync_forbid & allow
Part of T101073: after the view layer sync was made lazy (D15885), the
BKE_layer_collection_resync_forbid and BKE_layer_collection_resync_allow
in Alembic/USD/OBJ importers is no longer needed, as long as they do
view layer dependent operations (selecting new objects) in a separate
loop after creating all the objects.

Verified that this does not regress import times for 26k objects OBJ
scene (Blender 3.0 splash) and 250k objects USD scene (Moana).
2022-10-10 14:06:54 +03:00
42b1a7d4c6 OBJ: add global scale factor import setting
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.
2022-10-10 10:10:46 +03:00
210f4db81c Cleanup: spelling in comments 2022-10-10 11:22:41 +11:00
bd2f002e71 Fix T101685: OBJ importer does not assign proper material if "usemtl" is before "o"
The importer logic was wrongly resetting "current material name"
upon encountering a new object ("o" command). However as per OBJ
specification, this is incorrect:

> Specifies the material name for the element following it. Once a
> material is assigned, it cannot be turned off; it can only be
> changed.

Fixes T101685. Test coverage for this was added in svn tests repo.
2022-10-09 21:21:31 +03:00
c2fb85282d OBJ: extend importer tests to test imported material expectations
Previously "which material got assigned to an object in the end"
was not covered by tests. This is preparation for fixing T101685.
2022-10-09 20:52:23 +03:00
331f850056 Cleanup: redundant parenthesis 2022-10-07 22:55:03 +11:00
7029f11439 Fix T101487: New OBJ importer handles UVs incorrectly when some faces of an object don't have UVs
The UV data filling logic was incorrectly just skipping over loop
entries that don't have a UV coordinate, instead of assigning
the default zero UV for them. This was a problem only for meshes
where some faces did have UVs, but some other faces did not (T101487).
2022-10-03 11:07:50 +03:00
333e41eac6 Cleanup: replace C-style casts with functional casts for numeric types
Use function style casts in C++ headers & source.
2022-09-26 17:58:36 +10:00
6275541df7 Cleanup: use ELEM/STR_ELEM/STREQ macros 2022-09-26 14:12:38 +10:00
f68cfd6bb0 Cleanup: replace C-style casts with functional casts for numeric types 2022-09-25 20:17:08 +10:00
c7b247a118 Cleanup: replace static_casts with functional casts for numeric types 2022-09-25 18:31:10 +10:00
891949cbb4 Cleanup: use 'u' prefixed integer types for brevity & cast style
To use function style cast '(unsigned char)x' can't be replaced by
'unsigned char(x)'.
2022-09-25 18:26:27 +10:00
c9e35c2ced Cleanup: remove redundant double parenthesis 2022-09-25 15:34:32 +10:00
12becbf0df Mesh: Move selection flags to generic attributes
Using the attribute name semantics from T97452, this patch moves the
selection status of mesh elements from the `SELECT` of vertices, and
edges, and the `ME_FACE_SEL` of faces to generic boolean attribute
Storing this data as generic attributes can significantly simplify and
improve code, as described in T95965.

The attributes are called `.select_vert`, `.select_edge`, and
`.select_poly`. 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.

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 selection is used. When the flags are removed
completely, requirements will decrease.

Further notes:
* The `MVert` flag is empty at runtime now, so it can be ignored.
* `BMesh` is unchanged, otherwise the change would be much larger.
* Many tests have slightly different results, since the selection
  attribute uses more generic propagation. Previously you couldn't
  really rely on edit mode selections being propagated procedurally.
  Now it mostly works as expected.

Similar to 2480b55f21
Ref T95965

Differential Revision: https://developer.blender.org/D15795
2022-09-23 10:45:07 -05:00
e5d4afd5ba Depsgraph: generalize passing parameters to depsgraph object iterator
This makes it easier to pass more parameters to the iterator in the future.

Differential Revision: https://developer.blender.org/D16047
2022-09-23 12:41:22 +02:00
fbd78a8d78 Cleanup: use ELEM macro 2022-09-23 15:29:21 +10:00
Monique Dewanchand
68589a31eb ViewLayer: Lazy sync of scene data.
When a change happens which invalidates view layers the syncing will be postponed until the first usage.
This will improve importing or adding many objects in a single operation/script.

`BKE_view_layer_need_resync_tag` is used to tag the view layer to be out of sync. Before accessing
`BKE_view_layer_active_base_get`, `BKE_view_layer_active_object_get`, `BKE_view_layer_active_collection`
or `BKE_view_layer_object_bases` the caller should call `BKE_view_layer_synced_ensure`.

Having two functions ensures that partial syncing could be added as smaller patches in the future. Tagging a
view layer out of sync could be replaced with a partial sync. Eventually the number of full resyncs could be
reduced. After all tagging has been replaced with partial syncs the ensure_sync could be phased out.

This patch has been added to discuss the details and consequences of the current approach. For clarity
the call to BKE_view_layer_ensure_sync is placed close to the getters.
In the future this could be placed in more strategical places to reduce the number of calls or improve
performance. Finding those strategical places isn't that clear. When multiple operations are grouped
in a single script you might want to always check for resync.

Some areas found that can be improved. This list isn't complete.
These areas aren't addressed by this patch as these changes would be hard to detect to the reviewer.
The idea is to add changes to these areas as a separate patch. It might be that the initial commit would reduce
performance compared to master, but will be fixed by the additional patches.

**Object duplication**
During object duplication the syncing is temporarily disabled. With this patch this isn't useful as when disabled
the view_layer is accessed to locate bases. This can be improved by first locating the source bases, then duplicate
and sync and locate the new bases. Will be solved in a separate patch for clarity reasons ({D15886}).

**Object add**
`BKE_object_add` not only adds a new object, but also selects and activates the new base. This requires the
view_layer to be resynced. Some callers reverse the selection and activation (See `get_new_constraint_target`).
We should make the selection and activation optional. This would make it possible to add multiple objects
without having to resync per object.

**Postpone Activate Base**
Setting the basact is done in many locations. They follow a rule as after an action find the base and set
the basact. Finding the base could require a resync. The idea is to store in the view_layer the object which
base will be set in the basact during the next sync, reducing the times resyncing needs to happen.

Reviewed By: mont29

Maniphest Tasks: T73411

Differential Revision: https://developer.blender.org/D15885
2022-09-14 21:34:38 +02:00
Monique Dewanchand
23276bcc37 Adding const Scene* parameter in many areas.
Related to {D15885} that requires scene parameter
to be added in many places. To speed up the review process
the adding of the scene parameter was added in a separate
patch.

Reviewed By: mont29

Maniphest Tasks: T73411

Differential Revision: https://developer.blender.org/D15930
2022-09-14 21:30:56 +02:00
a99a62231e obj: implement support for PBR .mtl extensions
Implement import & export support for "PBR extensions" in .mtl files
(T101029, also fixes T86736).

Newly supported parameters:
- Roughness (Pr, map_Pr)
- Metallic (Pm, map_Pm)
- Sheen (Ps, map_Ps)
- Clearcoat thickness (Pc) and roughness (Pcr)
- Anisotropy (aniso) and rotation (anisor)
- Transmittance (Tf / Kt)

Exporter has an option to enable these additional PBR parameters
export; defaults to off since not all software understands that.

Exporter UI tweaked and all material-related options were put into
their own separate box.

Added/extended test files in Subversion repository for test coverage.
2022-09-13 15:01:29 +03:00
1a08a26388 Cleanup: spelling in comments 2022-09-13 13:24:44 +10:00
8af59cdb16 Cleanup: obj: rename MTLMaterial & MTLTexMapType members
The members were named after .mtl file syntax ("d") instead of their
meaning ("alpha"). In preparation for extending OBJ code for more
PBR parameters support, rename them for clarity. No functionality
changes, just a pure rename.
2022-09-12 21:05:57 +03:00
21f2bacad9 Cleanup: Simplify BKE_mesh_nomain_to_mesh
- Remove "take ownership" argument which was confusing and always true
  - The argument made ownership very confusing
  - Better to avoid boolean arguments that switch a function's purpose
- Remove "mask" argument which was basically wrong and not used properly
  - "EVERYTHING" was used because developers are wary of removing data
  - Instead use `CD_MASK_MESH` for its purpose of original mesh data
- Remove use of shallow copied temporary mesh, which is unnecessary now
- Split shape key processing into separate functions and use C++ types
- Copy fields explicitly rather than using memcpy for the whole struct
- Use higher level functions and avoid redundant code
  - The whole idea is pretty simple and can be built from standard logic
- Adjust `CustomData` logic to be consistent with "assign" expectations
  - Clear the layer data from the source, and moves the anonymous ID

Differential Revision: https://developer.blender.org/D15857
2022-09-09 08:29:46 -05:00
268e1eff8a Fix T96297: obj: improve layout of UI fields and axis validation
Implement ideas from T96297:
- Fix "invalid axis settings" (both forward & up along the same
  direction) validation: now similar to the Python based code, when
  invalid axis is applied, the other axis is changed to not conflict.
- Make axis enums be expanded inside the row, similar to Collada UI.
- Move "selected only" near the top, similar to how it's in Collada,
  USD, FBX and glTF export UIs.
- Move animation export options to the bottom.
2022-09-08 11:43:47 +03:00
d593497421 Cleanup: Use C++ methods to retrieve attribute accessors
Replace `mesh_attributes`, `mesh_attributes_for_write` and the point
cloud versions with methods on the `Mesh` and `PointCloud` types.
This makes them friendlier to use and improves readability.

Differential Revision: https://developer.blender.org/D15907
2022-09-07 21:41:39 -05:00
c2c369ebe6 Cleanup: prefer terms verts/polys over vertices/polygons
Follows existing naming for the most part, also use "num" as a suffix
in some instances (following our naming conventions).
2022-09-08 11:34:02 +10:00
67dcdebb3a Fix T100669: OBJ exporter does not properly export image sequence texture names
When exporting OBJ/MTL animation, texture file paths of image
sequences were not adjusted to contain the correct frame number.
Fixes T100669.

Also, the OBJ exporter was wrongly writing to the same .mtl file
for each exported frame, which is a regression compared to the
legacy Python exporter.
2022-09-07 17:56:21 +03:00
be038b844c Cleanup: Tweak naming for recently added mesh accessors
Use `verts` instead of `vertices` and `polys` instead of `polygons`
in the API added in 05952aa94d. This aligns better with
existing naming where the shorter names are much more common.
2022-09-07 00:06:31 -05:00