Add a new cleanup to 3D print tools #41093

Closed
opened 2014-07-16 03:02:50 +02:00 by Jenny Cheng · 12 comments

add_mesh_repair.patch

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

[add_mesh_repair.patch](https://archive.blender.org/developer/F98033/add_mesh_repair.patch) 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
Author

Changed status to: 'Open'

Changed status to: 'Open'
Campbell Barton was assigned by Jenny Cheng 2014-07-16 03:02:50 +02:00
Author

Added subscriber: @caretdashcaret

Added subscriber: @caretdashcaret

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.
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.
Author

refactor_mesh_repair.patch

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

http://www.blender.org/documentation/blender_python_api_2_71_release/bpy.ops.mesh.html?highlight=manifold#bpy.ops.mesh.select_non_manifold ]]
[refactor_mesh_repair.patch](https://archive.blender.org/developer/F101576/refactor_mesh_repair.patch) 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 | http://www.blender.org/documentation/blender_python_api_2_71_release/bpy.ops.mesh.html?highlight=manifold#bpy.ops.mesh.select_non_manifold ]] | -- |

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

3d_print_utils_nonmanifold_cleanup.diff

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.
Hi, thanks for the update, I had a look and made some changes, interested to know if they work for you. [3d_print_utils_nonmanifold_cleanup.diff](https://archive.blender.org/developer/F101708/3d_print_utils_nonmanifold_cleanup.diff) 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.
Author

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.

Screen_shot_2014-08-06_at_7.01.21_PM.png

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.

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. ![Screen_shot_2014-08-06_at_7.01.21_PM.png](https://archive.blender.org/developer/F101733/Screen_shot_2014-08-06_at_7.01.21_PM.png) 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.

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.
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.
Author

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

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 ](https:*github.com/caretdashcaret/MeshRepairTestModels)

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

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

Yup! The patch worked great!

I think you've also addressed my concerns.

Yup! The patch worked great! I think you've also addressed my concerns.

Committed a88a2e6460
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)
Committed a88a2e6460 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)

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender-addons#41093
No description provided.