GPv3: Fill texture coordinates data storage #114772

Closed
casey-bianco-davis wants to merge 22 commits from casey-bianco-davis/blender:GPv3-fill-texture into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.

This is proposes a new system for grease pencil v3 fill texture coordinates.

In the legacy system:

  • Textures could not be viewed when drawing.
  • Textures coordinates would not be maintained with any operator that changed the positions of points.
  • Change textures coordinates could only be done with the Transform Fill operator which was extremely unintuitive and hard to use.
  • The texture system was hard to use because textures would often be out of view.

This pull request adds:

  • System for storing and viewing texture coordinates.
  • Texture coordinates stay consistent during all operators.
  • Texture coordinates are convert when covering from legacy to GPv3
  • Textures are set to the drawing plane.

This system could allows for future features such as:

  • Projecting textures from view.
  • Transferring texture coordinates between curves.
  • Better tools for modifying texture coordinates.
  • Setting for how texture are placed when drawing.
This is proposes a new system for grease pencil v3 fill texture coordinates. In the legacy system: - Textures could not be viewed when drawing. - Textures coordinates would not be maintained with any operator that changed the positions of points. - Change textures coordinates could only be done with the `Transform Fill` operator which was extremely unintuitive and hard to use. - The texture system was hard to use because textures would often be out of view. This pull request adds: - System for storing and viewing texture coordinates. - Texture coordinates stay consistent during all operators. - Texture coordinates are convert when covering from legacy to GPv3 - Textures are set to the drawing plane. This system could allows for future features such as: - Projecting textures from view. - Transferring texture coordinates between curves. - Better tools for modifying texture coordinates. - Setting for how texture are placed when drawing.
casey-bianco-davis added 6 commits 2023-11-13 04:51:50 +01:00
casey-bianco-davis changed title from GPv3: New fill texture coordinates to GPv3: Fill texture coordinates system 2023-11-13 04:54:13 +01:00
Iliya Katushenock added this to the Grease Pencil project 2023-11-13 13:19:32 +01:00

So, that is just 2d position projection into surface of curve?

So, that is just 2d position projection into surface of curve?
Author
Member

So, that is just 2d position projection into surface of curve?

Yes, this system should look the same as the legacy system only differing in how the data is stored and accessed.

> So, that is just 2d position projection into surface of curve? Yes, this system should look the same as the legacy system only differing in how the data is stored and accessed.
Falk David requested review from Falk David 2023-11-16 10:49:45 +01:00
Falk David requested changes 2023-11-16 10:53:22 +01:00
Falk David left a comment
Member

Thanks for working on this 🙂 Just have a comment about the change to BLI for now.

Thanks for working on this 🙂 Just have a comment about the change to `BLI` for now.
@ -384,1 +382,4 @@
/** Multiply two compatible matrices using matrix multiplication. */
template<int OtherNumRow>
MatBase<T, OtherNumRow, NumRow> operator*(const MatBase<T, OtherNumRow, NumCol> &b) const
Member

Generally, changes to BLI should be in their own PR, preferably with a new test added to blender/source/blender/blenlib/tests/BLI_math_matrix_test.cc 😉

Generally, changes to `BLI` should be in their own PR, preferably with a new test added to `blender/source/blender/blenlib/tests/BLI_math_matrix_test.cc` 😉
casey-bianco-davis marked this conversation as resolved
casey-bianco-davis added the
Interest
Grease Pencil
label 2023-12-04 21:35:43 +01:00
casey-bianco-davis added 1 commit 2023-12-08 03:13:43 +01:00
casey-bianco-davis added 3 commits 2023-12-10 03:22:19 +01:00
casey-bianco-davis changed title from GPv3: Fill texture coordinates system to GPv3: Fill texture coordinates data storage 2023-12-11 22:15:25 +01:00
casey-bianco-davis added a new dependency 2023-12-12 04:51:14 +01:00
casey-bianco-davis added 2 commits 2023-12-27 03:46:45 +01:00
casey-bianco-davis changed title from GPv3: Fill texture coordinates data storage to WIP: GPv3: Fill texture coordinates data storage 2024-02-05 17:24:59 +01:00
casey-bianco-davis added 5 commits 2024-03-04 01:16:46 +01:00
casey-bianco-davis changed title from WIP: GPv3: Fill texture coordinates data storage to GPv3: Fill texture coordinates data storage 2024-03-04 01:18:08 +01:00
Author
Member

@filedescriptor All dependencies are done, this PR is ready to be reviewed.

@filedescriptor All dependencies are done, this PR is ready to be reviewed.
Falk David requested review from Lukas Tönne 2024-03-04 10:39:03 +01:00
Lukas Tönne requested changes 2024-03-04 13:58:27 +01:00
Lukas Tönne left a comment
Member

I think we should change the attributes to store a loc/rot/scale transform instead of the barycentric vectors + offset. I don't want to expose the legacy 3-point method unless necessary. And if the texture transform is already stored as general barycentric unit vectors then we might as well store the linear transform directly.

I think we should change the attributes to store a loc/rot/scale transform instead of the barycentric vectors + offset. I don't want to expose the legacy 3-point method unless necessary. And if the texture transform is already stored as general barycentric unit vectors then we might as well store the linear transform directly.
@ -868,0 +870,4 @@
* `curve_i` Note: the matrix returned does not represent an actual transformation and instead just
* stores the three points.
*/
blender::float3x3 get_texture_points(const blender::bke::CurvesGeometry &curves, int curve_i);
Member

This function is used only inside grease_pencil.cc, doesn't need to be exposed in the header.

Storing the points in a float3x3 is confusing, i would suggest returning e.g. float3[3]. Better yet, since these points are only used to compute an (orthonormal) transform the function could just do that and return a float4x4.

I had to implement the same function for the texture modifier. It won't be needed there anymore when this change goes in since the modifier would just change the linear transform.
2c9e34e168/source/blender/modifiers/intern/MOD_grease_pencil_texture.cc (L82-L101)

This function is used only inside grease_pencil.cc, doesn't need to be exposed in the header. Storing the points in a `float3x3` is confusing, i would suggest returning e.g. `float3[3]`. Better yet, since these points are only used to compute an (orthonormal) transform the function could just do that and return a float4x4. I had to implement the same function for the texture modifier. It won't be needed there anymore when this change goes in since the modifier would just change the linear transform. https://projects.blender.org/blender/blender/src/commit/2c9e34e16899d5faf138792bde0b2b4df65a2414/source/blender/modifiers/intern/MOD_grease_pencil_texture.cc#L82-L101
Author
Member

Currently get_texture_points is only used in the same file, but it will be used in a future PR.

I agree with not using float3x3 but I prefer std::array<float3, 3> over c-style arrays.

Currently `get_texture_points` is only used in the same file, but it will be used in a future PR. I agree with not using `float3x3` but I prefer `std::array<float3, 3>` over c-style arrays.
casey-bianco-davis marked this conversation as resolved
@ -1457,0 +1496,4 @@
MutableAttributeAccessor attributes = curves.attributes_for_write();
SpanAttributeWriter<float3> textU = attributes.lookup_or_add_for_write_span<float3>(
Member

I suggest to just store the loc/rot/scale instead of three vectors. That's a bit more flexible and doesn't rely so much on this arbitrary GPv2 method of picking three points to generate the transform.

The pair of get_texture_points/set_texture_points would then be replaced by get_stroke_plane_transform/set_stroke_plane_transform.

I suggest to just store the loc/rot/scale instead of three vectors. That's a bit more flexible and doesn't rely so much on this arbitrary GPv2 method of picking three points to generate the transform. The pair of `get_texture_points`/`set_texture_points` would then be replaced by `get_stroke_plane_transform`/`set_stroke_plane_transform`.
casey-bianco-davis marked this conversation as resolved
@ -159,0 +171,4 @@
/* Center of rotation. */
const float2 center = float2(0.5f, 0.5f);
const float2 uv_scale_inv = float2(uv_scale.x != 0.0f ? 1.0f / uv_scale.x : 1.0f,
Member

math::safe_rcp does 1/x with a null check

`math::safe_rcp` does 1/x with a null check
casey-bianco-davis marked this conversation as resolved
@ -159,0 +188,4 @@
textmat[2] += uv_translation;
/* Apply rotation. */
textmat[2] -= center;
Member

Could use math::from_origin_transform for this

Could use `math::from_origin_transform` for this
Author
Member

math::from_origin_transform doesn't work here because textmat is float3x2 and rot is float2x2 and math::from_origin_transform only works with same size matrices.

`math::from_origin_transform` doesn't work here because `textmat` is float3x2 and `rot` is float2x2 and `math::from_origin_transform` only works with same size matrices.
LukasTonne marked this conversation as resolved
@ -569,3 +570,2 @@
s_vert.u_stroke = length;
/* TODO: Populate fill UVs. */
s_vert.uv_fill[0] = s_vert.uv_fill[1] = 0;
copy_v2_v2(s_vert.uv_fill, texture_matrix * float4(pos, 1.0f));
Member

For applying a transform to a point use
math::transform_point(texture_matrix, pos)

For applying a transform to a point use `math::transform_point(texture_matrix, pos)`
Author
Member

math::transform_point does not work here because the texture matrix is 4x2, projecting points from 3D local-space to 2D texture-space. Whereas math::transform_point only works with 3D to 3D transformations.

`math::transform_point` does not work here because the texture matrix is 4x2, projecting points from 3D local-space to 2D texture-space. Whereas `math::transform_point` only works with 3D to 3D transformations.
Member

Ah, that's alright then, thanks for explaining.

Ah, that's alright then, thanks for explaining.
LukasTonne marked this conversation as resolved
@ -177,1 +179,4 @@
/* TODO: Align with the view or drawing plane. */
/* The default is the front draw plane (XZ). */
texture_points_ = float3x3(
Member

Is this going to be part of the patch or is it not possible atm for some reason?

Is this going to be part of the patch or is it not possible atm for some reason?
Author
Member

I was planing on adding more options and UI as a separate PR, so that this PR can be focused only on the storing, displaying and converting of the texture coordinates.

But I will add simple aligning with the drawing plane.

I was planing on adding more options and UI as a separate PR, so that this PR can be focused only on the storing, displaying and converting of the texture coordinates. But I will add simple aligning with the drawing plane.
casey-bianco-davis marked this conversation as resolved
Author
Member

I think that there has been a misunderstanding about what this PR does and how the texture coordinates are stored.

This PR creates three curve attributes, points U, V and Origin (accessed with texture_u, texture_v and texture_origin) which are points in local-space that represents the UV coordinates (1,0), (0,1) and (0,0) respectively.

I don't want to expose the legacy 3-point method unless necessary.

These three points are not the same as the "legacy 3-point method".

This PR also removes the attributes fill_translation, fill_rotation and fill_scale.
The three texture points (U, V, Origin) completely determent the texture coordinates.

So before what was store was 2 floats(fill_translation) + 1 float(fill_rotation) + 2 floats(fill_scale) (5 total floats), this transformation was with respect to the stroke in a very arbitrary and unintuitive way.

Whereas here we store 3 floats(texture_u) + 3 floats (texture_u) + 3 floats (texture_origin) (9 total floats), this transformation is completely regular and deterministic.

Note: some of the data stored in each point is redundant, as the point should be on the stroke's plane but can be stored not on the plane.
Why the data is stored this way is so that any operator that changes any point positions will automatically maintain the texture coordinates, (for instance deleting the last point in the legacy system would mess up the whole texture)
Another reason to store the data as points is to make working with Geometry Nodes as easy as possible (see the attached image)
I think that the eases of use with Geometry Nodes makes the redundant data worth it.

I think that there has been a misunderstanding about what this PR does and how the texture coordinates are stored. This PR creates three curve attributes, points U, V and Origin (accessed with `texture_u`, `texture_v` and `texture_origin`) which are points in local-space that represents the UV coordinates (1,0), (0,1) and (0,0) respectively. > I don't want to expose the legacy 3-point method unless necessary. These three points are not the same as the "legacy 3-point method". This PR also removes the attributes `fill_translation`, `fill_rotation` and `fill_scale`. The three texture points (U, V, Origin) completely determent the texture coordinates. So before what was store was 2 floats(`fill_translation`) + 1 float(`fill_rotation`) + 2 floats(`fill_scale`) (5 total floats), this transformation was with respect to the stroke in a very arbitrary and unintuitive way. Whereas here we store 3 floats(`texture_u`) + 3 floats (`texture_u`) + 3 floats (`texture_origin`) (9 total floats), this transformation is completely regular and deterministic. Note: some of the data stored in each point is redundant, as the point should be on the stroke's plane but can be stored not on the plane. Why the data is stored this way is so that any operator that changes any point positions will automatically maintain the texture coordinates, (for instance deleting the last point in the legacy system would mess up the whole texture) Another reason to store the data as points is to make working with `Geometry Nodes` as easy as possible (see the attached image) I think that the eases of use with `Geometry Nodes` makes the redundant data worth it.
casey-bianco-davis added 5 commits 2024-03-05 03:04:32 +01:00
casey-bianco-davis requested review from Lukas Tönne 2024-03-05 03:18:05 +01:00
Author
Member

There was a meeting talking about the texture coordinate system and a different method was decided on. PR #119303

There was a meeting talking about the texture coordinate system and a different method was decided on. PR #119303

Pull request closed

Sign in to join this conversation.
No reviewers
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Reference: blender/blender#114772
No description provided.