- edgebisect bmesh operator used uninialized beauty field.
- BLI_join_dirfile could read from before the string bounds when passed an empty dir string.
- pransform could use an uninitialized projected coordinate (unlikely but possible)
- RNA_property_path_from_ID_check would compare against an uninitialized pointer when the path wasn't found.
also have bmesh walker use BM_edge_other_vert() utility function.
- moved mesh conversion functions into their own file.
bmesh py api:
- can now create a new empty bmesh without first creating mesh data.
- added function to copy bmesh data back to a mesh.
- bmesh.from_mesh() can now get a mesh which isnt in editmode.
- BM_mesh_normals_update was looping over all faces to find the largest one, this is no longer needed.
- calculating a face normal was looping over every faces corners twice, now only once - using the loops directly (not an iterator).
- face vert locations were being copied an array, now use directly.
- calculating the normals would copy a float vector for the next point in the face, which was never used (only current and previous used).
- was copying vectors to compute the normal, now just assign the float pointers.
this fixes but [#30461] where the same vertex was added to some faces twice.
Previous code rebuilt all faces around the split edges, replace this with much simpler code that uses existing bmesh API for splitting.
This also gives a performance boost to the modifier (over 30x faster in the bug-report file).
* C: BM_vert_separate(...)
* py: bmesh.utils.vert_separate(vert, edges)
This splits off regions around the vertex, splitting on connected edges passed in a sequence.
also made minor changes
- rename python api functions _rip to _separate
- fixed bmesh iterator being iterable its self (some parts of python expect this)
- fix memory leak in bmesh python api.
Knifetool accumulates a bunch of proposed cuts and when the user
confirms, it makes them all. The old code did this by using scanfill
to triangulate the cutting edges in their faces, and then merging
triangles where possible. This sometimes ended up with strange
lost faces, and also made it so that when holes were cut, the
surrounding face ended up totally triangulated. But 29908 was
an example of a lost face.
This new code directly finds chains of cutting edges that go from
one side of a face to the other and using BM_edge_split_n to make
the cuts. Holes are handled by finding two good places where
the hole can be connected to the containing face (using two
because I think some other code in bmesh assumes that there are
no edges that appear twice in a face).
The old code is still there with #if SCANFILL_CUTS, so can easily revert
if this proves to be a bad idea.
Also, a small fix to previously added BM_split_n (forgot to
copy face attributes to new face).
turns out old code also had the same bug (just coincidance it was noticed after my change)
now boundry verts are tagged so edges connected to them are not seen is missing a tagged, adjacent edge.
this fixes [#30471]
Now create the rotate edge in advance and copy its customdata (before joining the faces).
This commit also fixes an annoyance where tryangulating faces could create duplicate edges.
On a user level, edge rotate now works better with multiple edges selected, it wont make zero area faces or rotate edges into existing ones.
With a single edge selected - rotate is less strict and will allow ugly resulting faces but still checks on duplicate edges.
API:
* BM_edge_rotate now takes a flag, to optionally...
** check for existing edge
** splice edge (rotate and merge)
** check for degenerate resulting faces (overlapping geometry, zero area)
** beauty - only rotate to a better fit.
... this allows it to still be used as a low level API function since all checks can be skipped.
* BM_edge_rotate() now works a bit different, it find the new edge rotation before joining the faces - exposed by BM_edge_rotate_calc().
* Added api call bmesh_radial_faceloop_find_vert() - Radial Find a Vertex Loop in Face
* optimize BM_face_other_edge_loop to do about half as many iterations for quad heavy meshes, with ngons the gain is much more since searching around the entire ngon when the edge already stores its loop is silly.
... also nicer in cases where edge has no face users it avoids a loop on all face corners.
* improve check to see if edge rotate can be done,
was checking if both edges verts have an edge count of 2, which is really a meaningless test since the verts can have stray edges connected and the result wont work right.
instead check if the next verts in both faces share a vertex.
* add utility function BM_face_other_vert_loop() which gets the next loop in a face.
* add convenience function BM_edge_face_pair() which returns 2 faces for edges that have exactly 2 face users. (saves ugly e->l->radial_next ... in code) and is more readable.
if blender freed the BMesh before python was finished (on exit editmode for eg), python would attempt to access the bmesh to clear python pointers in it.