Add-on to fit a cylinder to vertices

I previously updated two small add-ons that can fit a line or a plane to a collection of vertices and was asked if it was possible to create an add-on that fits a cylinder.

That is a bit more challenging though, but luckily there are people who spend some serious time on designing an algorithm and even providing code (see references below).

Based on that I created a small add-on that can indeed fit a cylinder to a collection of selected vertices. Note that it fits a cylinder where the vertices lie as closely as possible on the surface of the cylinder (see image). If you want to fit a cylinder that encloses all vertices, so more of a solid rod, simply use the linefit add-on and align a cylinder to the best fit line.


Usage

Simply download cyclinderfit.zip from the repo and install and enable the add-on from this zip-file.

Then select the mesh with the vertices you want to fit the cylinder to and select Fit cylinder from the Add menu (in edit mode). The new cylinder object will be added as a separate object that will be in edit mode.

Code availability

The code is available in this GitHub repository.

References

The cylinder fitting code was adapted from code in Xing Jiepan's repo, which in turn was based on the algorithms described in this paper by David Eberly.

To remove dependencies on external packages (except numpy, which is included with Blender), we replaced calls to the scikit.optimize.minimize function with a different implementation of Powells' minimization function from the Sherpa code-base of the Chandra project. 














Planefit.py and linefit.py updated for Blender 4.x

Always happy to see any of my add-ons being used, even if it's a really old one, so based on a BlenderArtists request I updated planefit.py and linefit.py.





Planefit adds a plane (=face) to your mesh that fits any selected vertices as well as possible (details in this post), and linefit is similar and adds a line (=edge) (details here). The articles also explain the math involved a bit if you are interested.

The updated add-ons can be found on GitHub:


Both add-ons can be downloaded in the same manner: Near the top right of the linked pages is a download button; click it to save the .py file, then (re)install the add-on in the usual manner.

Technical details

For any nerds out there: even though the commits seem large, that's mainly because I now use the Black formatter in all my Python projects so lots of whitespace was changed 😁. The actual change to planefit.py was only 1 line (the current line 116): the loop_total property of a polygon is read only nowadays so we cannot (and need not) set it: It is automatically updated when we add the vertex indices.

The change to linefit.py was a bit more involved, mainly because it was even older: Properties in an Operator are now annotated class variables (and have been since version 2.8 I think), so we had to change line 53 from

size = bpy.props.FloatProperty( ....

to

size : bpy.props.FloatProperty(...

A small but necessary change that does not even give you a warning anymore, so something to look out for if you revisit very old add-ons.

Likewise, the function bpy.utils.register_module() doesn't exist anymore and had to be replaced by bpy.utils.register_class()