Page MenuHome

Fix T86926 : Inconsistent behavior of knife tool
Needs ReviewPublic

Authored by Pratik Borhade (PratikPB2123) on Apr 4 2021, 2:52 AM.

Details

Summary

Fix T86926 .

Connect open ends of every edge-net to form a closed region.
Structure member open_v1, open_v2 created to store open end verts.

Before confirming the cut:

After confirming the cut:

Diff Detail

Repository
rB Blender

Event Timeline

Germano Cavalcante (mano-wii) requested changes to this revision.Apr 6 2021, 4:12 PM

Thanks for the patch.
Although we can see the edges. This change does not fix the problem.
The knife tool is not supposed to generate loose edges.
In your image, the result that I believe to be correct would be something like this drawing:


Where the red and yellow color represent the faces.

This revision now requires changes to proceed.Apr 6 2021, 4:12 PM
Pratik Borhade (PratikPB2123) edited the summary of this revision. (Show Details)
  • Boolean is_closed introduced : checks knife cut is closed or not

if knife cut is closed, join knife cut edge group and boundary edges with previous logic otherwise use first and last vert of knife cut for the connection.

  • New code block added to cast ray in both the directions Assign index to the integer variable index_other of closest BMVert

( casting ray in a single direction frequently produces loose edges )

  • New bool direction introduced : to cast the ray in opposite direction to the ray casted from the first knife vert
Germano Cavalcante (mano-wii) accepted this revision.EditedApr 16 2021, 4:57 PM

I did some tests. The result is still not perfect, but it is much better :)

bm_face_split_edgenet_find_connection is a somewhat complex function, and calling multiple times like this makes the code a little confusing.
Perhaps it would be good to make it clearer in comments what this code is doing.
Personally, I would prefer a new function to be created, something like:

static int bm_face_split_edgenet_find_nearest_non_intersecting_vert_for_connection(const struct EdgeGroup_FindConnection_Args *args, BMVert *v_origin, const short ignore_flag)

Choosing direction depending on what was found before is bad for readability and it doesn’t seem like something that would be planned for an original code.
So, although it improves the knife's behavior, I'm not sure if it's worth lowering the quality of the code in favor to improving such a little-used feature.

So, I am accepting the patch, but I will leave the final decision to @Campbell Barton (campbellbarton)

source/blender/bmesh/intern/bmesh_polygon_edgenet.c
1583

Follow the style guide for new comments: https://wiki.blender.org/wiki/Style_Guide/C_Cpp#Comments
(Uppercase for first letter; end with .)

This revision is now accepted and ready to land.Apr 16 2021, 4:57 PM
This revision now requires review to proceed.Apr 29 2021, 3:28 PM

The edge net functions are quite low level and intended to operate on complete nets (without handling loose ends).

I'd rater the knife tool code handles adding extra edges to connect the knife cut up to vertices of the face.


*Edit* this patch assumes the edge-net is a single line with two loose ends (based on a simple vertex/edge count check). Where an edge net can be any number of connected/disconnected edges. So this isn't a good place to resolve the issue.

Having said this, the knife tool can also be used to create arbitrary, disconnected cuts - using the E-key to create new cuts while the knife tool is running, e.g,

- although this is far less common.

So I think it's reasonable for the knife tool to take open loops and create edges connecting them to the face side.

More involved cases like the one above could work as they do now (not very well, however the expected result isn't so obvious either).

Campbell Barton (campbellbarton) requested changes to this revision.Apr 30 2021, 1:00 PM
This revision now requires changes to proceed.Apr 30 2021, 1:00 PM

Connect open ends of every edge-net to form a closed region.

  • Structure member open_v1, open_v2 created to store open end verts.

Before confirming the cut:

After confirming the cut: