Maniphest T41093

Add a new cleanup to 3D print tools
Closed, ResolvedPATCH

Assigned To
Campbell Barton (campbellbarton)
Authored By
Jenny Cheng (caretdashcaret)
Jul 16 2014, 3:02 AM
Tags
  • Add-ons (Community)
Subscribers
Campbell Barton (campbellbarton)
Jenny Cheng (caretdashcaret)

Description

Hello!

This patch adds a generic cleanup functionality to the 3D print tools for a more holistic mesh repair. I think this would make Blender rival some of the top mesh repair software like Netfabb and MeshLab.

It includes making all the vertices face the right way and patching up any holes (removing non-manifold vertices).

The basic algorithm is:

  1. find any non-manifold vertices
  2. fill
  3. find any non-manifold vertices (could be weird intersections caused by the fill)
  4. delete those vertices

The steps are looped until there are no more non-manifold vertices.

I developed the algorithm from experience.
I have reviewed a lot of mesh repair software:
http://caretdashcaret.wordpress.com/2013/07/17/how-to-fix-your-model-for-3d-printing-part-1/
http://caretdashcaret.wordpress.com/2013/08/09/how-to-fix-your-mesh-for-3d-printing-part-2/
http://caretdashcaret.wordpress.com/2013/09/26/autodesk-3d-print-utility-vs-netfabb/
http://caretdashcaret.wordpress.com/2014/05/19/meshmixer-first-impressions/

This patch passes all of my tests that I use for reviewing other mesh repair software.

I have a less-clean standalone add-on on my GitHub, but I think it should be integrated into the 3D printing toolkit.
https://github.com/caretdashcaret/MeshRepairFor3DPrinting

Thanks,
Jenny

Event Timeline

Jenny Cheng (caretdashcaret) created this task.Jul 16 2014, 3:02 AM
Jenny Cheng (caretdashcaret) assigned this task to Campbell Barton (campbellbarton).
Jenny Cheng (caretdashcaret) raised the priority of this task from to Normal.
Jenny Cheng (caretdashcaret) updated the task description.
Jenny Cheng (caretdashcaret) added a project: Add-ons (Community).
Jenny Cheng (caretdashcaret) edited a custom field.
Jenny Cheng (caretdashcaret) added a subscriber: Jenny Cheng (caretdashcaret).
Campbell Barton (campbellbarton) added a comment.Jul 23 2014, 11:36 AM

In general seems like it can be nice functionality to have.

Some concerns.

  • the chance of looping forever is risky. It would be good if blender has some way to press Escape to cancel long running python scripts.
  • this looks like it intends to operate on the entire mesh, so probably it should un-hide before beginning.

To better handle cases of really bad mesh data which possibly can't be fixed, I think the loop that checks while non_manifold_vertices > 0: It should really check if any changes where made as well.

So rather then looping while there is some manifold geometry, It should loop and keep fixing, as long as it can keep making fixes, Once no changes can be made - it can break out of the loop.


Other comments,

  • Recently add options for select manifold, probably its good to check on these: https://developer.blender.org/rB00cb9e5f1cfab142b0972f7a35c3247b00d56423#7dfccffc
  • bpy.ops.mesh.remove_doubles(use_unselected=True) why is use_unselected set? This is meant for merging unselected into selected, which doesnt make sense in this case?
  • bpy.ops.mesh.fill() takes a sides options, defaults to 4, probably good to set this. (and perhaps you want to set it higher? - not sure)
  • bpy.ops.mesh.dissolve_degenerate and bpy.ops.mesh.select_all take a threshold argument. Probably good if this operator defines a threshold and passes it to all operators it calls which also take a threshold.
Jenny Cheng (caretdashcaret) added a comment.Aug 6 2014, 4:00 AM

Thanks for reviewing!
I did a pretty big refactor, to try to address the comments you brought up.

I now terminate the loop if it exceeds a max iteration as well as terminate it if nothing was fixed in a particular iteration.

The operator now takes some arguments for threshold and default sides to fill.

I saw the options were added for selecting manifolds, but I didn't see how to specify the option in the API docs.
[[ http://www.blender.org/documentation/blender_python_api_2_71_release/bpy.ops.mesh.html?highlight=manifold#bpy.ops.mesh.select_non_manifold

Campbell Barton (campbellbarton) added a comment.Aug 6 2014, 9:48 PM

Hi, thanks for the update, I had a look and made some changes, interested to know if they work for you.

Summery of changes

  • was switching from editmode to object mode just to count selected vertices, now stay in editmode and simply count vertices.
  • use different method of checking when to break the cleanup loop:
rather than counting non-manifold geometry, store unique (totvert, totedge, totface), then keep cleaning until the same state is reached more than once.
  • removed some unused functions.
  • add self.delete_loose() once at the start (any reason you removed?)
  • postpone make_normals_consistently_outwards until after all cleaning is done.
Jenny Cheng (caretdashcaret) added a comment.EditedAug 7 2014, 1:03 AM

It looks great!
Thanks!
I definitely learned a few things from reading your code. :)

I think I accidentally deleted delete_loose().

I was worried about postponing make_normals_consistently_outwards, since I wasn't sure how edges in between faces with opposite normals would count, but it looks fine.

I tested it on Rakdos. It's the model that more naive repairs out there fail on. I can't attach the STL (or even a zipped STL) because it exceeds the size limit.

Do you think using unique (totvert, totedge, totface) will get false positives? Like the suppose the total number of vertices stayed the same, but the non manifold vertices themselves have changed (through some combination of fill() and delete). I'm not sure if this is likely or even possible.

Campbell Barton (campbellbarton) added a comment.Aug 7 2014, 4:45 AM

Regarding, make_normals_consistently_outwards - your right actually, I'll need to modify this to disable use_non_contiguous option, this way edges will be ignored between flipped faces. Probably theres no use in having use_multi_face option enabled either (3+ edges to a face).

Would you be able to upload the test file and link the URL here? - so I can check my edits work ok.

Re: (totvert, totedge, totface) giving false positives, think the likelyhood is so low as to not being worth worrying about (in fact impossible at the moment).

  • Vertices are always removed (never added).
  • Faces are always added (except when verts are removed that collapse faces).

... so I cant see chance that both stay same when an edit is made.

Jenny Cheng (caretdashcaret) added a comment.Aug 7 2014, 2:44 PM

I've uploaded the files to GitHub. It's not a huge sample size, but I think it's somewhat representative of the cases.

https://github.com/caretdashcaret/MeshRepairTestModels

Campbell Barton (campbellbarton) added a comment.Aug 7 2014, 7:45 PM

@Jenny Cheng (caretdashcaret) - to be clear, does the current version of this patch work as you'd expect?

Jenny Cheng (caretdashcaret) added a comment.Aug 8 2014, 1:19 AM

Yup! The patch worked great!

I think you've also addressed my concerns.

Campbell Barton (campbellbarton) added a comment.Aug 11 2014, 1:29 AM

Committed rBAa88a2e646018b3f9b8d1f818f0a08370b2a0dd67
With some edits

  • Control whats selected by select_non_manifold_verts.
  • Report a message showing verts added/removed on completion.
  • use staticmethods/classmethods (so functions only use whats passed to them)
Campbell Barton (campbellbarton) changed the task status from Unknown Status to Resolved.Aug 11 2014, 1:29 AM