Dynamic-topology sculpt mode is in trunk

Sculpted from a single quad. I swear my real-life handwriting is better.

It’s finally done! Huge, huge thanks to everyone that helped out with test builds, bug reports, suggestions, code review, donations, encouragement, and of course awesome test images! The models and renders in the Dyntopo tests thread on BlenderArtists are really something to see.

Although dyntopo won’t be in an official release of Blender until 2.66 comes out in February, any test builds made from trunk r53450 or later will have dyntopo. Please check out the documentation, play around with the tool, and report any bugs you find to the Blender 2.6 bug tracker. Thanks again everybody!

Time for some more dynamic topology testing

Although I’ve been quiet on the website, I’ve continued work on dynamic topology sculpt mode. All of this work has been of the non-exciting variety; there are no new features, just cleaner and more robust code. In particular it took a while to figure out how to get everything in the undo system to fit together, but it’s working pretty well now in terms of stability. Undo/redo of masking and hiding works now too. The smooth shading toggle is more robust, the info header stats show new vertices and faces created during sculpting, and the mesh wireframe toggle is fixed.

With the code now much closer to being merge ready, I’d like to get some user testing to shake out bugs and find things I’ve overlooked. I’m particularly interested in ways to crash dynamic topology, problems with undo/redo, and problems with saving or loading. If you find a way to reliably reproduce an issue please describe it in the comments. (I’ve been keeping a list of test cases for undo/redo, that’s the sort of steps-to-reproduce I need.) Please check that you have an up-to-date build before reporting issues. The code is still in the dyntopo-slim branch here: https://github.com/nicholasbishop/blender/tree/dyntopo-slim

Another thing I could use a hand with is getting an icon for the “Enable Dynamic” button. Right now it’s reusing the remesh modifier’s icon as a placeholder.

There is still a significant amount of work left to do before dynamic topology can be merged into trunk, but we’re getting closer now. Thanks to everyone who has helped the project along.

Update: just pushed (4:03UTC, Dec 4) a fix for a crash when collapsing edges.

Symmetrize in trunk

Beveled text, symmetrized and subsurf’d.

The symmetrize operator is now in trunk, r51356.

Since the 2.64 release, I’ve been getting a few of the commits from the dyntopo branch finalized and into trunk. The symmetrize operator is a nice independent piece of code from dyntopo, much as the convex hull operator was an independent piece of the skin modifier.

Note that during the code review for symmetrize some fixes were made; hopefully it should work better with dyntopo now. In particular, there was a bug that caused small unattached faces to hang around the plane of symmetry. That should be fixed now.

Thanks to Brecht for reviewing the code.

If you find any bugs, please report them in the regular Blender bug tracker.

Development continues on dyntopo as well. Most of the work is still related to the undo system, but there have been other stability fixes and code cleanups as well. Of note is that the layer brush no longer crashes.

Initial push of updated dyntopo undo code

As mentioned last week, I’m working on a different approach to handling undo in dyntopo. The new code is up in the usual place on a branch called dyntopo-slim.

The dyntopo branch has 36 commits touching 107 files with 7406 insertion and 624 deletions. The dyntopo-slim branch has only 25 commits and touches 51 files with 5377 insertions and 258 deletions.

The latter set of numbers will no doubt increase, but it should be clear that the new method is much less intrusive. It’ll be quicker to review and easier to maintain. Further, it should be more memory efficient.

The new code is not yet complete; it won’t work with the symmetrize operator (which is temporarily disabled), it’s leaking memory sometimes, and it’s leaving more loose edges lying around. (Dealing with loose edges is a general todo that needs solving in dyntopo.)

If you’re feeling brave, give the new branch a try. If you find crashes with undo/redo let me know, and I’m also curious to hear how memory usage compares.

Variations on Undo

I’m experimenting with a different method of undo for dyntopo. If successful, it will use less memory and affect fewer parts of the code outside sculpting. It’s still in the early stages, and not pushed publicly anywhere. Just wanted to pass that along so that y’all know the project is still moving forward.

“It’s a maker…”

Status update: I’ve just started a non-Blender-related job as a developer at a company called MakerBot that sells 3D printers. What with moving from South Carolina to Brooklyn and the usual getting-up-to-speed at the new job I’ve been a bit busy. I’m still working on dyntopo as time allows, and I expect that as I settle in, my Blender projects will pick up steam again.

My current focus is on finalizing parts of dyntopo that could be committed separately. The largest such component is the BMLog, which is what dyntopo is using for undo/redo. Rather than making full copies of the BMesh, it keeps track of the Euler operators applied to the mesh (and their inputs), and undoing simply applies the inverse operator.

If necessary, BMLog could be added as an optional system that is only enabled for dyntopo, but if possible I’d like it to handle undo in editmode as well. This will ensure it gets proper testing, and should generally be advantageous in terms of memory usage as well. I’m currently making the necessary changes to use BMLog for editmesh undo so that I can give it some better testing.

BMLog also needs thorough developer documentation and various code cleanups to meet my own standards. I’ll be going through each commit to do my own code review as well, before proposing it for inclusion in Blender (at which point, if there is interest from other developers, it will get additional review before being included in Blender.)

The 2.64 release is still planned for sometime in September. It’ll be nice to see that code finally get out the door; it’ll be the first official release with sculpt masking and the skin modifier. I’m hopeful that BMLog can be proposed for inclusion in 2.65, but that will depend on my schedule and feedback from other developers (who may be busy with GSoC merges.)

Dyntopo+symmetrize undo

The symmetrize work is now pretty much completed. I resolved the issues with BMLog (for undo/redo), and learned a bit more about BMesh’s internal structure at the same time.

There are more “nice to have” features that might yet happen for symmetrize. In particular I might experiment with more aggressive merging across the axis boundary to avoid small edges/faces in that region. For now though, it’s hopefully stable and usable, so I have merged the relevant commits into the main dyntopo branch.

Incidentally, since symmetrize is a BMesh operator in its own right, I will probably look at getting it into trunk separately from dyntopo. That will be after 2.64 is released, of course.

Also: I’d like to say a big thanks to all the people who have donated recently. It is much appreciated, and I look forward to “repaying” you all by getting dyntopo finished as soon as possible.

Symmetrize and dyntopo

Don’t have much spare time right now, but still slowly hacking away on integrating symmetrize and dyntopo. The existing work is in the dyntopo-symmetrize branch. It works except for undo, which is what I’m working on now.

Actually, symmetrize itself already works fine with undo, but re-triangulating the mesh after symmetrizing relies on the SFME (split face, make edge) BMesh euler operator, which is not supported in BMLog. I added that support in, but discovered that the inverse operator JFKE (join faces, kill edge) does not always act as a true inverse. Thanks to the Suzanne mesh for showing me that case.

Currently altering SFME and JFKE to behave as I think they should, then BMLog can be updated, and finally dyntopo-symmetrize can be completed. Once all that is done, all the work will be moved into the dyntopo branch and dyntopo-symmetrize & co. will go away.

Symmetrize improved

Suzanne symmetrized twice in different directions, then subsurf’d to demonstrate that the geometry remains connected.

I’ve pushed some fresh updates to symmetrize. It should in general behave much better:

  • Normals are recalculated correctly.
  • Fixed cracks appearing along the axis of some meshes.
  • Fixed crash when operator is run from sculpt mode.
  • Axis and direction are now selectable when running the operator.
  • Improved memory management.
  • General code cleanups, main symmetrize code is now in blenkernel.

Note that this is still Mesh-only (not BMesh), so doesn’t work for dynamic topology sculpting or edit mode yet.


Since the dawn of time (i.e. since SharpConstruct) sculpt symmetry essentially works as though multiple brushes are operating on the mesh simultaneously. This is not necessarily the most efficient method, but it is easy to implement and is generally fairly robust. It is even serviceable with dynamic topology, which is somewhat surprising considering that no attempt is made to keep the topology symmetric. That said, imperfections do begin to pop up with dynamic topology, so a workaround would be nice.

Symmetric Suzannes
Naturally the first thing I had to do was go all Photo Booth on Suzanne.

While there are certainly fancy options such as dynamically mirroring the mesh while sculpting and constantly re-stitching the center, a simpler alternative is to add an operator that the user can manually invoke to symmetrize the mesh. (I was inordinately happy to discover that symmetrize is an actual word.)

I’ve just gotten a basic implementation working, code available as usual from my Blender Github repository, symmetrize branch.

To test it, just select a mesh and spacebar-search for the symmetrize operator. Only works in object mode for now. Once the algorithm is solid for meshes I’ll add a BMesh version. Note that right now it’s hardcoded to symmetrize across the YZ plane from X- to X+.

It’s actually a bit harder to symmetrize than you might expect; there are a significant number of cases to think through. A few examples follow:

A mesh consisting of a hexagon, pentagon, and three quads being symmetrized.
  • Any polygon that is already symmetric across the axis will end up just as it started. The pentagon and square demonstrate this.
  • In general, a polygon that is not symmetric across the axis gets chopped in half — everything on one side of the axis gets thrown away, and the rest is copied over and mirrored. The hexagon at left demonstrates this.
  • An exception is made for asymmetric polygons that have some symmetric edges. For example, the two quads adjacent to the square do not get split down the middle, as that would require the nice square to become a hexagon. Instead, a triangle is added to separate the asymmetric polygon from the symmetric one, and then a mirrored copy is added.

There are actually more cases — I’m still working on dealing with polygons that cross the axis multiple times. Loose edges should also be mirrored. It may be helpful to add additional cleanups too, such as optional merging of thin polygons that are sometimes generated near the axis.

As noted, this is just a regular mesh operator for now, not yet part of the dynamic topology branch. I’ll merge it in once the tool is nicely stabilized, but I should mention that I don’t currently have a lot of time to work on Blender.