Bevel operator calculates wrong offsets #78472

Closed
opened 2020-06-30 21:42:23 +02:00 by Thor Ekle · 17 comments

System Information
Operating system: Win 10 Pro
Graphics card: nVidia GTX 2070 Super

Blender Version
Broken: 2.83.1
Worked: unknown; was broken in 2.79

Short description of error
The bevel operator calculates incorrect offsets for the new edges in some cases. In Offset mode, the distance from the original edge to the new edges is supposed to be "the distance of a new edge from the original." This is not true in many (most?) cases.

Exact steps for others to reproduce the error

  • Starting point is the default startup file.

  • Hit Tab to enter edit mode.

  • Hit Ctrl R to add an edge loop parallel to the Y axis, then Enter twice to confirm.

  • Hit Ctrl B, then enter 0.1 to specify the bevel offset.

  • Verify that the amount mode is Offset and the Segments is set to 1.

  • Observe that the X positions of the two new edges are 0.1 and -0.1, respectively -- this is expected behavior.

  • Undo all steps.

  • Enter face select mode, then select the face that is parallel with the Y axis and with an X position of -1.0.

  • Type S Y 0.5 and hit Enter to scale the face along the Y axis.

  • Hit Ctrl R to add an edge loop parallel to the Y axis, then Enter twice to confirm.

  • Hit Ctrl B, then enter 0.1 to specify the bevel offset.

  • Verify that the bevel settings are as above.

  • Observe that the X positions of the two new edges are 0.098462 and -0.098462, respectively -- this is NOT expected behavior.

The distances from the new edges to the original should be 0.1 in both cases.

bevel bug.jpg

**System Information** Operating system: Win 10 Pro Graphics card: nVidia GTX 2070 Super **Blender Version** Broken: 2.83.1 Worked: unknown; was broken in 2.79 **Short description of error** The bevel operator calculates incorrect offsets for the new edges in some cases. In Offset mode, the distance from the original edge to the new edges is supposed to be "the distance of a new edge from the original." This is not true in many (most?) cases. **Exact steps for others to reproduce the error** - Starting point is the default startup file. - Hit Tab to enter edit mode. - Hit Ctrl R to add an edge loop parallel to the Y axis, then Enter twice to confirm. - Hit Ctrl B, then enter 0.1 to specify the bevel offset. - Verify that the amount mode is Offset and the Segments is set to 1. - Observe that the X positions of the two new edges are 0.1 and -0.1, respectively -- this is expected behavior. - Undo all steps. - Enter face select mode, then select the face that is parallel with the Y axis and with an X position of -1.0. - Type S Y 0.5 and hit Enter to scale the face along the Y axis. - Hit Ctrl R to add an edge loop parallel to the Y axis, then Enter twice to confirm. - Hit Ctrl B, then enter 0.1 to specify the bevel offset. - Verify that the bevel settings are as above. - Observe that the X positions of the two new edges are 0.098462 and -0.098462, respectively -- this is NOT expected behavior. The distances from the new edges to the original should be 0.1 in both cases. ![bevel bug.jpg](https://archive.blender.org/developer/F8655750/bevel_bug.jpg)
Author

Added subscriber: @thorie

Added subscriber: @thorie

Added subscriber: @deadpin

Added subscriber: @deadpin

In 2.90 a new bevel mode called "Absolute" was added which should give you more expected results in both cases here. If possible can you check this in 2.90 to see if it solves your case? In both cases above the new edge segment generated by the bevel will be exactly 0.2

In the meantime, the documentation for "Offset" mode should probably be reworded to better explain the parameters under which it operates.

In 2.90 a new bevel mode called "Absolute" was added which should give you more expected results in both cases here. If possible can you check this in 2.90 to see if it solves your case? In both cases above the new edge segment generated by the bevel will be exactly 0.2 In the meantime, the documentation for "Offset" mode should probably be reworded to better explain the parameters under which it operates.
Author

I may be able to test 2.90 in a day or two -- thanks!

And I agree that the documentation should be reworded; it reads as if the distance is measured perpendicularly to the original edge. Which begs the question... how IS the distance currently measured?

In #78472#970069, @deadpin wrote:
In 2.90 a new bevel mode called "Absolute" was added which should give you more expected results in both cases here. If possible can you check this in 2.90 to see if it solves your case? In both cases above the new edge segment generated by the bevel will be exactly 0.2

In the meantime, the documentation for "Offset" mode should probably be reworded to better explain the parameters under which it operates.

I may be able to test 2.90 in a day or two -- thanks! And I agree that the documentation should be reworded; it reads as if the distance is measured perpendicularly to the original edge. Which begs the question... how IS the distance currently measured? > In #78472#970069, @deadpin wrote: > In 2.90 a new bevel mode called "Absolute" was added which should give you more expected results in both cases here. If possible can you check this in 2.90 to see if it solves your case? In both cases above the new edge segment generated by the bevel will be exactly 0.2 > > In the meantime, the documentation for "Offset" mode should probably be reworded to better explain the parameters under which it operates.

Added subscriber: @iss

Added subscriber: @iss

In #78472#970069, @deadpin wrote:
In 2.90 a new bevel mode called "Absolute" was added which should give you more expected results in both cases here. If possible can you check this in 2.90 to see if it solves your case? In both cases above the new edge segment generated by the bevel will be exactly 0.2

In the meantime, the documentation for "Offset" mode should probably be reworded to better explain the parameters under which it operates.

Does that work for you? It doesn't seem to produce desired result

> In #78472#970069, @deadpin wrote: > In 2.90 a new bevel mode called "Absolute" was added which should give you more expected results in both cases here. If possible can you check this in 2.90 to see if it solves your case? In both cases above the new edge segment generated by the bevel will be exactly 0.2 > > In the meantime, the documentation for "Offset" mode should probably be reworded to better explain the parameters under which it operates. Does that work for you? It doesn't seem to produce desired result

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'

I can confirm this based on documentation, I think it's worded quite precisely

I can confirm this based on documentation, I think it's worded quite precisely
Author

In #78472#970117, @iss wrote:
I can confirm this based on documentation, I think it's worded quite precisely

Sorry to be so dense... but I'm not sure I understand? Are you saying the documentation is worded precisely or that my bug report is? :)

> In #78472#970117, @iss wrote: > I can confirm this based on documentation, I think it's worded quite precisely Sorry to be so dense... but I'm not sure I understand? Are you saying the documentation is worded precisely or that my bug report is? :)

I think that documentation is worded quite precisely, and it does not match actual behavior.

I think that documentation is worded quite precisely, and it does not match actual behavior.
Author

In #78472#970999, @iss wrote:
I think that documentation is worded quite precisely, and it does not match actual behavior.

Right -- we are on the same page.

> In #78472#970999, @iss wrote: > I think that documentation is worded quite precisely, and it does not match actual behavior. Right -- we are on the same page.
Author

I just tested this in 2.90, and the new Absolute mode does not solve the issue described in the initial post.

While the length of the new edge segment is 0.2 in this mode, the distance between the two loops (obviously) is not -- and this was the original problem. None of the modes create new loops with a distance of 0.1 from the original loop. It seems more important to correctly calculate this distance than the length of the new segment(s).

As an aside, the M shortcut key (to switch between modes before confirming) seems to skip the new Absolute mode. Let me know if you want me to report that separately.

I just tested this in 2.90, and the new Absolute mode does not solve the issue described in the initial post. While the length of the new edge segment is 0.2 in this mode, the distance between the two loops (obviously) is not -- and this was the original problem. None of the modes create new loops with a distance of 0.1 from the original loop. It seems more important to correctly calculate this distance than the length of the new segment(s). As an aside, the M shortcut key (to switch between modes before confirming) seems to skip the new Absolute mode. Let me know if you want me to report that separately.
Member

Added subscriber: @howardt

Added subscriber: @howardt
Member

The code is working as intended.
Sometimes it is impossible to get the offset to be the exact amount specified on all edges simultaneously. This is the case in the example you have explained how to construct. When this happens, bevel has to do the best it can in an overconstrained situation, which will mean some (maybe all) of the actual offsets will be slightly off.

Note that if you remove all but the top of the second cube (the one with the scaled face), then do the bevel, you get the x values as you expect -- 0.1 and -0.1, as they should be (measured perpendicularly from the original edge at x = 0).

Now look at the sides of the second cube. because they aren't parallel to the x-axis, the distance measured perpendicularly from the center edge loop is longer than the distance measured perpendicularly from the center edge loop on the top and bottom. It is impossible to have the distance be the offset on all four sides and still have them meet at the same place on the 4 edges going (roughly) in the x-direction. I regard it as more expected that bevel not split the connection point on those 4 edges than that it exactly obey the offset specification.

Should I change the documentation to explicitly say that sometimes it is impossible to satisfy all of the offset requirements simultaneously?

The code is working as intended. Sometimes it is impossible to get the offset to be the exact amount specified on all edges simultaneously. This is the case in the example you have explained how to construct. When this happens, bevel has to do the best it can in an overconstrained situation, which will mean some (maybe all) of the actual offsets will be slightly off. Note that if you remove all but the top of the second cube (the one with the scaled face), then do the bevel, you get the x values as you expect -- 0.1 and -0.1, as they should be (measured perpendicularly from the original edge at x = 0). Now look at the *sides* of the second cube. because they aren't parallel to the x-axis, the distance measured perpendicularly from the center edge loop is *longer* than the distance measured perpendicularly from the center edge loop on the top and bottom. It is impossible to have the distance be the offset on all four sides and still have them meet at the same place on the 4 edges going (roughly) in the x-direction. I regard it as *more* expected that bevel not split the connection point on those 4 edges than that it exactly obey the offset specification. Should I change the documentation to explicitly say that sometimes it is impossible to satisfy all of the offset requirements simultaneously?
Author

I see your point, and I definitely think the documentation should be changed as you suggest.

However, this does not solve the issue from the user point of view. I think it's safe to say that most users expect the behavior I described in the initial post -- and that should be an important consideration.

One approach would be to give precedence to the current transformation orientation (global, local or custom) when calculating the offset. In my example, the intent clearly is to calculate the offset along the local X-axis; the distance measured along the side is not of interest. And in case the user actually wants to measure the distance along the side, it's a simple matter of adding a custom orientation.

This approach would let the user decide which offset requirements are important and have those calculated according to the user's needs, rather than having potentially all offsets fail to obey the specification.

Given that the UI already has a prominent and easy-to-use transform orientation selector, making this change need not affect the UI at all -- unless you want to give users the option of reverting to the old behavior; that would require a checkbox. Alternatively, this could be implemented as a new mode.

Regardless, I think this would be an important improvement that's also in line with the basic behavior of blender; GS&R all obey the selected transform orientation, for example.

In #78472#1021374, @howardt wrote:
The code is working as intended.
Sometimes it is impossible to get the offset to be the exact amount specified on all edges simultaneously.

I see your point, and I definitely think the documentation should be changed as you suggest. However, this does not solve the issue from the user point of view. I think it's safe to say that most users expect the behavior I described in the initial post -- and that should be an important consideration. One approach would be to give precedence to the current transformation orientation (global, local or custom) when calculating the offset. In my example, the intent clearly is to calculate the offset along the local X-axis; the distance measured along the side is not of interest. And in case the user actually wants to measure the distance along the side, it's a simple matter of adding a custom orientation. This approach would let the user decide which offset requirements are important and have those calculated according to the user's needs, rather than having potentially all offsets fail to obey the specification. Given that the UI already has a prominent and easy-to-use transform orientation selector, making this change need not affect the UI at all -- unless you want to give users the option of reverting to the old behavior; that would require a checkbox. Alternatively, this could be implemented as a new mode. Regardless, I think this would be an important improvement that's also in line with the basic behavior of blender; GS&R all obey the selected transform orientation, for example. > In #78472#1021374, @howardt wrote: > The code is working as intended. > Sometimes it is impossible to get the offset to be the exact amount specified on all edges simultaneously.
Member

Changed status from 'Confirmed' to: 'Archived'

Changed status from 'Confirmed' to: 'Archived'
Howard Trickey self-assigned this 2020-09-23 13:15:03 +02:00
Member

"most users expect the behavior described in the initial post"

Really? I think there is an equally valid expectation that ALL edges selected to be beveled get the right offset. In your mind, you were trying to get a particular width along the x axis, but others might be trying to get a constant width of the band on the surface of the object that the band is going around (which is impossible, as I've pointed out, but as a user, that would be MY expectation).

I'm not totally opposed to tie-breaking rules but am dubious that a rule like "prefer to get the width right on edges most perpendicular to the x axis of the current transform" is useful enough to go to the effort of programming that in (I'd have to change the structure of the code somewhat to pass that transform in, and it will get kind of ugly because the transform isn't always available or relevant (think: API and modifiers). So I'm not going to implement this tie breaking rule right now. If you think this is wrong, and an essential necessity, try drumming up support for this point of view on BlenderArtists or blender.devtalk and I might change my mind.

For now, I'm going to close this thread and update the blender manual as I proposed above.

"most users expect the behavior described in the initial post" Really? I think there is an equally valid expectation that ALL edges selected to be beveled get the right offset. In your mind, you were trying to get a particular width along the x axis, but others might be trying to get a constant width of the band on the surface of the object that the band is going around (which is impossible, as I've pointed out, but as a user, that would be MY expectation). I'm not totally opposed to tie-breaking rules but am dubious that a rule like "prefer to get the width right on edges most perpendicular to the x axis of the current transform" is useful enough to go to the effort of programming that in (I'd have to change the structure of the code somewhat to pass that transform in, and it will get kind of ugly because the transform isn't always available or relevant (think: API and modifiers). So I'm not going to implement this tie breaking rule right now. If you think this is wrong, and an essential necessity, try drumming up support for this point of view on BlenderArtists or blender.devtalk and I might change my mind. For now, I'm going to close this thread and update the blender manual as I proposed above.
Sign in to join this conversation.
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.

Dependencies

No dependencies set.

Reference: blender/blender#78472
No description provided.