WIP: Snap Individual: improvements with mixed Face Nearest and Face Project #116149

Draft
Germano Cavalcante wants to merge 1 commits from mano-wii/blender:transform_mixed into main

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

When Individual Face Project is enabled, occluded elements being
transformed are moved in front of the occluding object.

This is old behavior, and may even be desirable in some cases.

But when we enable Face Nearest together, it seems to be more
advantageous to use Nearest for occluded elements.

Therefore, this commit changes the behavior of Face Project + Nearest
so that Nearest is used not only for elements that don't hit an object,
but also for elements that are occluded.

When Individual Face Project is enabled, occluded elements being transformed are moved in front of the occluding object. This is old behavior, and may even be desirable in some cases. But when we enable Face Nearest together, it seems to be more advantageous to use Nearest for occluded elements. Therefore, this commit changes the behavior of Face Project + Nearest so that Nearest is used not only for elements that don't hit an object, but also for elements that are occluded.
Germano Cavalcante added the
Module
Sculpt, Paint & Texture
label 2023-12-13 15:51:46 +01:00
Germano Cavalcante requested review from Julien Kaspar 2023-12-13 15:52:16 +01:00
Member

@blender-bot build

@blender-bot build
Member

@blender-bot build package

@blender-bot build package
Member

Unknown platform package. See documentation for details.

Unknown platform `package`. See [documentation](https://projects.blender.org/infrastructure/blender-bot/src/branch/main/README.md) for details.
Member

@blender-bot package

@blender-bot package
Member

Package build started. Download here when ready.

Package build started. [Download here](https://builder.blender.org/download/patch/PR116149) when ready.
Member

Now I got it. Sorry :D

Now I got it. Sorry :D
Member

It's almost working well afaiks.
The snapping seems unstable and some selected elements fly off into infinity.
image
They flicker a lot. Maybe because the keep switching between Face Nearest or Projecting into the background?

It's almost working well afaiks. The snapping seems unstable and some selected elements fly off into infinity. ![image](/attachments/1545c400-6e6c-4482-a4e7-13ed93f7e893) They flicker a lot. Maybe because the keep switching between Face Nearest or Projecting into the background?
346 KiB
Author
Member

They flicker a lot. Maybe because the keep switching between Face Nearest or Projecting into the background?

Fixed.

I didn't know that I couldn't use FLT_MAX for maximum distance in ED_transform_snap_object_project_ray_ex. Must be BVH_RAYCAST_DIST_MAX.

@blender-bot package

> They flicker a lot. Maybe because the keep switching between Face Nearest or Projecting into the background? Fixed. I didn't know that I couldn't use `FLT_MAX` for maximum distance in `ED_transform_snap_object_project_ray_ex`. Must be `BVH_RAYCAST_DIST_MAX`. @blender-bot package
Member

Package build started. Download here when ready.

Package build started. [Download here](https://builder.blender.org/download/patch/PR116149) when ready.
Member

For the most part this already works exactly like expected and is a big timesaver!
But I still think comparing for example individual vertex normals of the selected mesh with the view angle could get us better results. Maybe you also have an idea @mano-wii ?

Here are some cases where the occlusion logic fails:

There are still regular cases where vertices along a loop cut will snap to something in the distance, because they were no longer on top of the part of the object right next to them. This will happen a lot on overlapping shapes.

There are also going to be lots of cases where the Face Nearest snapping is getting it wrong the first time and instead snaps to the backside of an object.
In that case the combined snapping won't fix this, since it's always occluded on the side it's supposed to be snapped to.

image

But when looking at the vertex normals, we can see that the vertex is roughly facing the view and verices along the rim of shapes are roughly at a right angle away from us.

For the most part this already works exactly like expected and is a big timesaver! But I still think comparing for example individual vertex normals of the selected mesh with the view angle could get us better results. Maybe you also have an idea @mano-wii ? Here are some cases where the occlusion logic fails: There are still regular cases where vertices along a loop cut will snap to something in the distance, because they were no longer on top of the part of the object right next to them. This will happen a lot on overlapping shapes. <video src="/attachments/e612fb03-f939-4b93-898e-1bba09d6d760" title="2023-12-14 10-03-54.mp4" controls></video> There are also going to be lots of cases where the Face Nearest snapping is getting it wrong the first time and instead snaps to the backside of an object. In that case the combined snapping won't fix this, since it's always occluded on the side it's supposed to be snapped to. ![image](/attachments/ca55317b-2791-413a-be68-7e8955a958c0) But when looking at the vertex normals, we can see that the vertex is roughly facing the view and verices along the rim of shapes are roughly at a right angle away from us.
Author
Member

The proposed solution of checking the normal of the vertices with the direction of the view and using some factor to decide between nearest or project adds a lot of complexity to the code since it would be necessary to store information about the original normals before the transformation.
To implement this, we would also have to consider other types of objects with transformable points:

  • Armature
  • Curves (hair, bezier, surface..)
  • Lattice
  • Metaball

And adds some questions:

  • What to do with points that we can't get the normal?
  • What would be the ideal factor? Should it be adjustable?

From the point of view of someone who maintains the transform code, the benefit of this feature does not compensate for the complexity it would add to the code :\

The proposed solution of checking the normal of the vertices with the direction of the view and using some factor to decide between nearest or project adds a lot of complexity to the code since it would be necessary to store information about the original normals before the transformation. To implement this, we would also have to consider other types of objects with transformable points: - Armature - Curves (hair, bezier, surface..) - Lattice - Metaball And adds some questions: - What to do with points that we can't get the normal? - What would be the ideal factor? Should it be adjustable? From the point of view of someone who maintains the transform code, the benefit of this feature does not compensate for the complexity it would add to the code :\
Germano Cavalcante changed title from Transform: Test occlusion in individual Face Project if Nearest is also enabled to WIP: Transform: Test occlusion in individual Face Project if Nearest is also enabled 2024-01-18 13:48:57 +01:00
Author
Member

I think I found a solution.
If the angle created by: nearest position, original position, projected position, is greater than 45 degrees, use the nearest position.
This would be a generic solution that doesn't add much complexity.
It might be worth testing.

I think I found a solution. If the angle created by: nearest position, original position, projected position, is greater than 45 degrees, use the nearest position. This would be a generic solution that doesn't add much complexity. It might be worth testing.
Member

EDIT:

I think I found a solution.

That sounds great! Let's try that.


In the case of Armatures, Curves, Metaballs and Lattices it would make sense to fall back on the current implementation of the PR. In general if there are points that we can't get a normal from.

The ideal factor is something to find out. I think it would be fine to land it as an experimental feature at first with a factor setting that the user can tweak. Once it's clear that there's an ideal setting, that can be the default and the setting can be removed.
I can be responsible for stress testing the feature.

In terms of benefits vs complexity it's hard to judge from my point of view.
I can only speak in favor of improving it further because the current state in main is very time consuming and frustrating and the current PR is still often leading to problematic results.

Aren't there various edit mode operators that use the original normal of the selection? Shrink/Fatten as a direct example of using individual vertex normals.

EDIT: > I think I found a solution. That sounds great! Let's try that. --- In the case of Armatures, Curves, Metaballs and Lattices it would make sense to fall back on the current implementation of the PR. In general if there are points that we can't get a normal from. The ideal factor is something to find out. I think it would be fine to land it as an experimental feature at first with a factor setting that the user can tweak. Once it's clear that there's an ideal setting, that can be the default and the setting can be removed. I can be responsible for stress testing the feature. In terms of benefits vs complexity it's hard to judge from my point of view. I can only speak in favor of improving it further because the current state in `main` is very time consuming and frustrating and the current PR is still often leading to problematic results. Aren't there various edit mode operators that use the original normal of the selection? Shrink/Fatten as a direct example of using individual vertex normals.
Germano Cavalcante force-pushed transform_mixed from 54fef8d406 to 18b6763490 2024-01-18 15:38:22 +01:00 Compare
Author
Member

I implemented the solution I had in mind.
It no longer depends on the normal, so it applies to all types of objects.

I made this ugly drawing to try to explain the solution:
Sem título.jpg

One thing in this patch that perhaps deserves attention is the occlusion test.
Currently it is done with the transformed position without snapping (which can be a little unpredictable as the user may not know where the vertex would be without the snap).
Should the occlusion test only be done at the beginning to detect hidden vertices and therefore only have the nearest snap?

@blender-bot package

I implemented the solution I had in mind. It no longer depends on the normal, so it applies to all types of objects. I made this ugly drawing to try to explain the solution: ![Sem título.jpg](/attachments/65def18e-0d55-4976-ac0d-6b207ace2097) One thing in this patch that perhaps deserves attention is the occlusion test. Currently it is done with the transformed position without snapping (which can be a little unpredictable as the user may not know where the vertex would be without the snap). Should the occlusion test only be done at the beginning to detect hidden vertices and therefore only have the nearest snap? @blender-bot package
Member

Package build started. Download here when ready.

Package build started. [Download here](https://builder.blender.org/download/patch/PR116149) when ready.
Member

I tested it for a bit. This update solves the core issue I pointed out!
As I see it this combined snapping will never lead to drastic position changes. And if the position changes a subtle it will use Projected snapping, which is more responsive 👍

Maybe there could be a better factor than 45 degrees? Right now it results in 'Face Nearest' snapping happening way more often.

If we want to fine tune this I'd love to tune the factor while testing and see a debug color overlay which vertex is using which snapping. But if that's too much time and effort we can stick to 45 degrees.

What do you think?


The update won't fix this issue:

There are also going to be lots of cases where the Face Nearest snapping is getting it wrong the first time and instead snaps to the backside of an object.
In that case the combined snapping won't fix this, since it's always occluded on the side it's supposed to be snapped to.

But that ok. Temporarily disabling snapping or using a transform operator that doesn't use snapping can also fix those issues.

I tested it for a bit. This update solves the core issue I pointed out! As I see it this combined snapping will never lead to drastic position changes. And if the position changes a subtle it will use Projected snapping, which is more responsive 👍 Maybe there could be a better factor than 45 degrees? Right now it results in 'Face Nearest' snapping happening way more often. If we want to fine tune this I'd love to tune the factor while testing and see a debug color overlay which vertex is using which snapping. But if that's too much time and effort we can stick to 45 degrees. What do you think? --- The update won't fix this issue: > There are also going to be lots of cases where the Face Nearest snapping is getting it wrong the first time and instead snaps to the backside of an object. In that case the combined snapping won't fix this, since it's always occluded on the side it's supposed to be snapped to. But that ok. Temporarily disabling snapping or using a transform operator that doesn't use snapping can also fix those issues.
Member

Currently it is done with the transformed position without snapping (which can be a little unpredictable as the user may not know where the vertex would be without the snap).
Should the occlusion test only be done at the beginning to detect hidden vertices and therefore only have the nearest snap?

It's a bit hard to picture a case where the occlusion test really adds something to the new behavior.
Would there be any case where the surface that occludes the transformed position (basically same as projected position) is having an angle lower than 45 degrees to the nearest position? I find it hard to think of an example.

So maybe it doesn't matter.

> Currently it is done with the transformed position without snapping (which can be a little unpredictable as the user may not know where the vertex would be without the snap). Should the occlusion test only be done at the beginning to detect hidden vertices and therefore only have the nearest snap? It's a bit hard to picture a case where the occlusion test really adds something to the new behavior. Would there be any case where the surface that occludes the transformed position (basically same as projected position) is having an angle lower than 45 degrees to the nearest position? I find it hard to think of an example. So maybe it doesn't matter.
Member

@mano-wii Do you think we should do some more testing? Otherwise I'm also fine with merging the current state 👍

@mano-wii Do you think we should do some more testing? Otherwise I'm also fine with merging the current state 👍
Author
Member

Maybe there could be a better factor than 45 degrees? Right now it results in 'Face Nearest' snapping happening way more often.

If the vertex is in front of the Mesh, it will almost always be Face Project, maybe what is happening is the occlusion?
With occlusion, if you move a vertex that is on the side of an object towards the object, the vertex moves to inside the object (occluded), so Nearest is used in this case.

The image below shows the case described. The black triangle at the bottom is the observer. The vertex (Green) is being moved in the direction indicated by the arrow.
In this case, the observer might expect the vertex to be projected onto the Mesh (gray) when the vertex passes through it.
But with this patch, technically the vertex is occluded and Face Nearest is being used instead of Face Project.
image

I'm not sure if this is desirable. Perhaps it's worth testing alternative solutions to occlusion. I have in mind a somewhat complex idea that involves checking distances and the direction of the snap movement (if the direction is opposite, use the Nearest; otherwise, check the distances and use the snap that is closer to the observer).

> Maybe there could be a better factor than 45 degrees? Right now it results in 'Face Nearest' snapping happening way more often. If the vertex is in front of the Mesh, it will almost always be Face Project, maybe what is happening is the occlusion? With occlusion, if you move a vertex that is on the side of an object towards the object, the vertex moves to inside the object (occluded), so Nearest is used in this case. The image below shows the case described. The black triangle at the bottom is the observer. The vertex (Green) is being moved in the direction indicated by the arrow. In this case, the observer might expect the vertex to be projected onto the Mesh (gray) when the vertex passes through it. But with this patch, technically the vertex is occluded and Face Nearest is being used instead of Face Project. ![image](/attachments/fbed11a9-8754-44b1-ac8d-0cedb0eaca5d) I'm not sure if this is desirable. Perhaps it's worth testing alternative solutions to occlusion. I have in mind a somewhat complex idea that involves checking distances and the direction of the snap movement (if the direction is opposite, use the Nearest; otherwise, check the distances and use the snap that is closer to the observer).
Member

@mano-wii Ok I think I understand. I think the current implementation is good. Even on very complex models like the Skull of the Blender Base Meshes, the snapping never fails to snap to the correct surface.
That is the most important part.

One issue I could still point out is that once there's a switch in the snapping method on selected elements, it jumps drastically in position. This is a only bit jarring on single vertices. But on selected patches or loops of geometry this is problematic.

An idea to improve this: When the snapping method is switched to Nearest Face on at least one selected element, it's switched for the entire selection. A consistent transformation behavior across the selection is more predictable and useful.

@mano-wii Ok I think I understand. I think the current implementation is good. Even on very complex models like the Skull of the Blender Base Meshes, the snapping never fails to snap to the correct surface. That is the most important part. One issue I could still point out is that once there's a switch in the snapping method on selected elements, it jumps drastically in position. This is a only bit jarring on single vertices. But on selected patches or loops of geometry this is problematic. An idea to improve this: When the snapping method is switched to Nearest Face on at least one selected element, it's switched for the entire selection. A consistent transformation behavior across the selection is more predictable and useful. <video src="/attachments/573ed8e1-a3b8-4f32-9ea5-80dece563619" title="2024-01-29 14-38-47.mp4" controls></video>
Germano Cavalcante force-pushed transform_mixed from 18b6763490 to f0a5071e0a 2024-01-29 16:20:37 +01:00 Compare
Author
Member

I tested a different occlusion strategy, but it didn't really help. In the end I combined the two and it was the same thing.

You can test with the experimental options.
And you can test different angles:
image

@blender-bot package

I tested a different occlusion strategy, but it didn't really help. In the end I combined the two and it was the same thing. You can test with the experimental options. And you can test different angles: ![image](/attachments/8df5a300-281f-4904-b7c8-c734be5d8a4e) @blender-bot package
Member

Package build started. Download here when ready.

Package build started. [Download here](https://builder.blender.org/download/patch/PR116149) when ready.
Member

I don't really notice a difference between "Test Occlusion + Angle" and "Test Depth + Angle".
The angle of 45 degrees works really well. Anything above that leads to more snapping issues.

There are some cases where Projected snapping is used where I think it is exceeding the 45 degree value. Not sure what's happening here.
Lowering the angle can mitigate this but doesn't fully solve it.

While Moving After. Seen from the above
I don't really notice a difference between "Test Occlusion + Angle" and "Test Depth + Angle". The angle of 45 degrees works really well. Anything above that leads to more snapping issues. There are some cases where Projected snapping is used where I think it is exceeding the 45 degree value. Not sure what's happening here. Lowering the angle can mitigate this but doesn't fully solve it. | While Moving| After. Seen from the above | | -------- | -------- | | ![](attachments/b62a30e9-9405-4140-9bc4-2e7a6579ce24) | ![](attachments/30f47290-1eb7-4da5-9f48-cde5ef999975) |
Germano Cavalcante force-pushed transform_mixed from f0a5071e0a to 08f3cd4b56 2024-02-16 16:08:45 +01:00 Compare
Author
Member

I've been thinking about solutions to the issue of inclusion, and I believe I've found a good one.
The rules for choosing the snap are:

  • If the Nearest snap point is occluded (behind the object), the snap project is not performed for the point;
  • If both Nearest and Project are visible, calculate the angle formed between the initial position at the nearest and the initial position at the project, if this angle is less than 30 degrees, choose the Project , otherwise choose the Nearest.

@blender-bot package

I've been thinking about solutions to the issue of inclusion, and I believe I've found a good one. The rules for choosing the snap are: - If the Nearest snap point is occluded (behind the object), the snap project is not performed for the point; - If both Nearest and Project are visible, calculate the angle formed between the initial position at the nearest and the initial position at the project, if this angle is less than 30 degrees, choose the Project , otherwise choose the Nearest. @blender-bot package
Member

Package build started. Download here when ready.

Package build started. [Download here](https://builder.blender.org/download/patch/PR116149) when ready.
Author
Member

The angle of 45 degrees works really well. Anything above that leads to more snapping issues.

I hadn't seen that message!
However, it looks like there was an error in the previous code. The angle was inverted (bigger was smaller).

You can still edit the preferences and put 45 degrees back.

> The angle of 45 degrees works really well. Anything above that leads to more snapping issues. I hadn't seen that message! However, it looks like there was an error in the previous code. The angle was inverted (bigger was smaller). You can still edit the preferences and put 45 degrees back.
Member

@mano-wii I tested it out a bit and the behavior is now the wrong way around. At directly view facing faces the Nearest snapping is used, while steep angles use the Projected snapping.

Also what do you think about my suggestion from a previous comment?

An idea to improve this: When the snapping method is switched to Nearest Face on at least one selected element, it's switched for the entire selection. A consistent transformation behavior across the selection is more predictable and useful.

@mano-wii I tested it out a bit and the behavior is now the wrong way around. At directly view facing faces the Nearest snapping is used, while steep angles use the Projected snapping. Also what do you think about my suggestion from a previous comment? > An idea to improve this: When the snapping method is switched to Nearest Face on at least one selected element, it's switched for the entire selection. A consistent transformation behavior across the selection is more predictable and useful.
Germano Cavalcante changed title from WIP: Transform: Test occlusion in individual Face Project if Nearest is also enabled to WIP: Snap Individual: improvements with mixed Face Nearest and Face Project 2024-02-26 15:51:31 +01:00
All checks were successful
buildbot/vexp-code-patch-lint Build done.
buildbot/vexp-code-patch-darwin-arm64 Build done.
buildbot/vexp-code-patch-darwin-x86_64 Build done.
buildbot/vexp-code-patch-linux-x86_64 Build done.
buildbot/vexp-code-patch-windows-amd64 Build done.
buildbot/vexp-code-patch-coordinator Build done.
This pull request has changes conflicting with the target branch.
  • source/blender/blenkernel/BKE_blender_version.h
  • source/blender/blenloader/intern/versioning_400.cc
  • source/blender/editors/transform/transform.cc
  • source/blender/editors/transform/transform_snap.cc
  • source/blender/makesdna/DNA_userdef_types.h
  • source/blender/makesrna/intern/rna_userdef.cc

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u transform_mixed:mano-wii-transform_mixed
git checkout mano-wii-transform_mixed
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
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#116149
No description provided.