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