Bolt Factory Addon: RemoveDoubles() improvements #2
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally blender/blender-addons#105066 from @sw-tya
System Information
Operating system: Linux Mint 21.2 Victoria base: Ubuntu 22.04 jammy
Graphics card: OpenGL: renderer: Mesa Intel HD Graphics 4000 (IVB GT2) v: 4.2 Mesa 23.3.0
Blender Version
Broken: 3.0.1
Worked: Probably never? It has been 6 years since the last main branch edit to this function, assuming I looked in the right place.
Addon Information
Name: BoltFactory (0, 4, 0)
Author: Aaron Keith
Short description of error
While looking to clean up the non-manifold parts of the Bolt Factory library I have found a couple of things which should be addressed within the RemoveDoubles() function inside createMesh.py :
Duplicate faces are not removed.
The built-in round function does not find similar values depending on the precision.
Function description; it would have been helpful to state, Verts that are not matched to a Face of length 3 or 4 are silently expunged.
Please note that I'm not a software engineer :)
Exact steps for others to reproduce the error
Towards the end of createMesh.py, just before "verts = Scale_Mesh_Verts(verts, GLOBAL_SCALE)" add the following lines:
props.report({'INFO'}, "length of verts before RemoveDoubles: " + str( len(verts) ) )
props.report({'INFO'}, "length of faces before RemoveDoubles: " + str( len(faces) ) )
verts, faces = RemoveDoubles(verts, faces, 4)
props.report({'INFO'}, "length of faces after RemoveDoubles 4DP: " + str( len(faces) ) )
props.report({'INFO'}, "length of verts after RemoveDoubles 4DP: " + str( len(verts) ) )
verts, faces = RemoveDoubles(verts, faces, 5) # Needs to be 5 to fix non-manifold boundary on a M6 nut
props.report({'INFO'}, "length of faces after RemoveDoubles 5DP: " + str( len(faces) ) )
props.report({'INFO'}, "length of verts after RemoveDoubles 5DP: " + str( len(verts) ) )
verts, faces = RemoveDoubles(verts, faces, 6) # 6 to check we got them all
props.report({'INFO'}, "length of faces after RemoveDoubles 6DP: " + str( len(faces) ) )
props.report({'INFO'}, "length of verts after RemoveDoubles 6DP: " + str( len(verts) ) )
if 0: #Set true to capture the output data to the debug window.
props.report({'INFO'}, "Final_Nut_Verts = " + str( (verts) ) )
props.report({'INFO'}, "Final_Nut_Faces = " + str( (faces) ) )
In a new project, enable the Bolt Factory addon if not already setup.
Add -> Mesh -> BoltFactory
OperatorPresent -> m6
Model -> Nut
Type -> Hex
Observe the Info Log window, as see that Verts length of "RemovedDoubles 5DP" is less than RemovedDoubles 4DP.
For me this gives the following:
length of verts after RemoveDoubles 4DP: 1342
length of verts after RemoveDoubles 5DP: 1339
There are several parts to this ticket I'd like to have a crack at addressing. Game plan:
Removing duplicate faces. Leaving a mesh with duplicate faces is not ideal as it creates non-manifold objects.
Checking for a duplicate face is testing a list of verts against an existing dictionary. Minor complication is that order does matter, as order sets the top side. I think it should be a matter of doing a cyclic shift then testing 3 or 4 times.
Add 1 level of recursion to resolve the mathematical rounding.
The alternative method would be a vector radius to test if any point resides within a sphere of another point. I expect this would be more computationally expensive than two passes of rounding vectors and comparing.
The rounding causes faces to end up with fewer than 3 sides. Which is fine. However it might be nice to check for a slither, that is two faces pointing in opposite directions. The validate mesh catches this preventing a crash, but knowing where it occurred would help debug and find the point where the generation requires fixing.
Finally the easy bit, add some documentation. While playing around I discovered it was impossible to make a face with 5 or more sides. Not a problem if it documented, as it can be worked around.
Why: The start and end thread generation in a nut can create an invalid mesh - this was previously attempted to be fixed by adding a random offset, which does not always work.