Page MenuHome

Sculpt mode UI/UX design
Open, NormalPublic

Tokens
"Love" token, awarded by Jaydead."Love" token, awarded by Krayzmond."Love" token, awarded by lopoIsaac."Love" token, awarded by brilliant_ape."Love" token, awarded by KINjO."Love" token, awarded by xrg."Love" token, awarded by elbox01.
Assigned To
None
Authored By

Description

The purpose of this task is to discuss the UI/UX design of the features included in the sculpt-mode-features branch.

Cursor, normal radius and brush parameters

Open questions:

  • Right now the cursor is disabled when previewing textures and in any other paint mode. Should we support this even if the modes are not compatible with normal projection internally?
  • Curve presets are nice to have, but they are conflicting with the curve option of the brush. The most important curve preset right now is the smooth curve for grab, so we can:
    • Disable the curve presets completely and add an option to the grab brush to use the hardcoded smooth curve
    • Merge the curve presets and the brush curve panel into one, with a “use curve preset” checkbox
  • A normal radius of 0.0 won’t produce any deformation (the same as 0 radius or 0 strength), but this option is currently hidden inside a popover. Should we add this option to the top bar, or maybe show a warning when sculpting with 0 normal radius?
  • Normal radius behaves weirdly with dyntopo enabled. This is expected, as you can’t crease an edge while collapsing it. Should normal radius default to 1 when dyntopo is enabled?

Remeshers

Blender should include several remeshers, designed both for blocking and for automatic retopology to use the sculpt with the multires modifier. They should have the following properties:

  • The remeshers configuration should be stored per mesh. This includes the desired algorithm with its parameters and the reprojection options (mask, vertex, weights). This is especially important for the voxel remesher, which needs to be run several times when blocking a sculpt without interrupting the workflow.
  • The remesher options will be displayed in the top bar, next to dyntopo. The configuration is stored in the mesh datablock, so maybe it should also be displayed in the mesh datablock panel.
  • The remesh modifier could read these options from the datablock when added and apply them. This should be useful when working with OpenVDB booleans from sculpt mode.

Open questions:

  • Right now you can undo a remesh operator, but you can’t redo it from the undo stack without applying the remesher again, as it would require to copy the whole mesh resulting for the remesher twice (once for undo and once for redo). Should this be supported?
  • A quad extractor remesher could take several minutes to finish. How are we going to display this in the interface? Should it block the whole interface when running?
  • Should we limit the size of the OpenVDB grid size? Some users working on really small objects reported that the current voxel size limits are not enough to achieve the desired level of detail, but giving the option to go directly to a small voxel size with a huge mesh will crash Blender.
  • Which quad extractor remesher are we going to support? Right now we have LibIGL/QEX in the branch, but Quadriflow should be better and with fewer dependencies. Can we develop a custom quad extractor remehser?

Sculpt Vertex Colors

The sculpt vertex color data is not compatible with the current vertex color data. In order to keep supporting the functionality of the current vertex colors, we could do the following:

  • Keep the current vertex paint mode as it is. This mode will affect color data stored in the loops.
  • Sculpt mode should have a global “affect colors” toggle. When enabled, compatible brushes should expose color options and color pickers and palletes should be displayed.
    • When enabling this option, the user should be warned because he/she may lose color data. Sculpt vertex colors are stored per vertex, so they can only store a single color per vertex.
  • Blender should copy the color data from the active regular loop color layer into sculpt mode vertex color layer. Once the user switches the active color layer or exits sculpt mode, the color data will be copied back to the loop color layer. This approach is relatively easy to implement, but it is not compatible with painting from sculpt mode with EEVEE enabled.

Open questions:

  • Which brushes should support vertex colors?
  • When vertex colors from sculpt mode are enabled, the brush texture should be interpreted as a color texture or as an alpha?
  • Right now the branch has a Paint Brush in sculpt mode, which only affects vertex colors, optimizing the undo operation. Should this be kept?
  • If we port all the vertex paint tools to sculpt vertex colors we can leave the current vertex paint mode as an “attribute paint” mode for the everything nodes project. For that kind of task, brush behavior and performance won’t be that important, and we are going to reuse a lot of code from sculpt mode. Can this option be considered?
  • Other option could be keeping the current vertex paint mode while switching all the internals to sculpt vertex colors. The IU should be exactly the same, but internally you are going enter sculpt mode when selecting vertex paint. This also brings the advantages of more code reuse, better brushes, performance… but we may lose the ability to have a vertex color per face.

Mesh, mask and color filters

These tools implement several operations which affect the mesh as a whole. The user can select the desired filter from the toolbar and apply it by dragging the cursor on the viewport.

Open questions:

  • Some filters, like smooth, require several iterations to be useful. Previewing this in real time would take an insane amount of memory. How can we solve this?
  • Real-time preview support for some filters may take a lot of resources. Should we add an option to apply the filter directly without the interactive preview? We can’t use the redo panel for the same reason, unless we add some kind of "update" button to it to apply the changes manually.
  • It would be very useful to have the mask filters mapped to the keymap by default, we should find good default for this, as switching to the mask filter tool each time you create a mask is not a good workflow.

Transform tool

The transform tool uses the same gizmos, snapping and constraints as any other transform operator in Blender. This tool is often used for posing, so it includes several operators to position the pivot point automatically, as well as the mask expand operator, specially designed for posing characters.

Open questions:

  • We need to think about how to implement all the set pivot position options. This could be a “set pivot” menu, similar to the “merge” menu of edit mode.
  • The transform tool should have a “move pivot only” option. For this to work, it would be nice to have the gizmo always visible during transform. Should this be added as a tools setting, as a keymap option or as a separate tool?
  • The mask expand operator should also be added to the transform tool keymap from sculpt mode. Could it be mapped to a mouse click and drag gesture?
  • Should we use the 3D cursor as the default pivot for the transform tool? This way, users would be familiar with the operators to position the pivot, but that was not the intended use for the 3D cursor
  • We can’t rely on the redo panel for the same reason explained in the mesh filters section, so maybe the redo panel should be disabled. Are we going to support redoing transform operations with another method?

Masking tools and automasking stack

The automasking stack should allow the user to use several automasking operations at the same time. For example, it should be possible to grab only the vertex connected topologically, ignoring edge borders, and affecting creases with a 50% strength. The UI for this could be quite complex. So, in the first version, supporting only topological masking with a checkbox should be enough.

Open questions:

  • The branch includes several masking operators which are really useful (mask by color, mask by normal…). These operators depend on the active vertex highlighted by the cursor, so they only can be executed from the keymap. How can we add intuitive shortcuts for this?
  • Furthermore, some of these mask generation tools have a lot of parameters (tolerance, invert…). These parameters can’t be changed from the redo panel for performance reasons (which in my opinion would be the ideal solution). How can we solve this? Should we add a new tool for every mask generation tool?
  • Currently, the mask by color operator takes all the color components into consideration. Should it only take the hue into consideration?

Details

Type
Design

Event Timeline

Right now the cursor is disabled when previewing textures and in any other paint mode. Should we support this even if the modes are not compatible with normal projection internally?

Not sure I understand the question. If some mode does not use normal projection, it can display a cursor but without taking into account the normal?

A normal radius of 0.0 won’t produce any deformation (the same as 0 radius or 0 strength), but this option is currently hidden inside a popover. Should we add this option to the top bar, or maybe show a warning when sculpting with 0 normal radius?

If it's exactly 0.0 that does not produce any deformation, then we should not allow it to be set to that? If it's any small radius that is smaller than faces, then can't we have some fallback if not enough geometry is detected under the brush?

If it should be at the top level or not I guess depends if it's an option that you need to tweak often, ideally only for artistic control if it can be made to work well enough on different geometry.

Normal radius behaves weirdly with dyntopo enabled. This is expected, as you can’t crease an edge while collapsing it. Should normal radius default to 1 when dyntopo is enabled?

What do you mean by "crease an edge while collapsing it"?

I can imagine that if the normal is based on few faces with a small normal radius, and dyntopo is changing these faces, that the normal can be quite unstable. And with small normal radius this would be worse than full normal radius. But maybe you are referring to something else.

Right now you can undo a remesh operator, but you can’t redo it from the undo stack without applying the remesher again, as it would require to copy the whole mesh resulting for the remesher twice (once for undo and once for redo). Should this be supported?

Is this about saving memory in the undo stack, or is there some limitation in the undo code that makes this not work?

A quad extractor remesher could take several minutes to finish. How are we going to display this in the interface? Should it block the whole interface when running?

This is like baking or rendering. This can be a modal operator that has a progress bar and keeps the UI responsive, but blocks most user interaction that could disrupt the remeshing. If there's some interactive progress to display that would be best, but for remeshing it may be hard to show much useful info besides a progress bar.

Should we limit the size of the OpenVDB grid size? Some users working on really small objects reported that the current voxel size limits are not enough to achieve the desired level of detail, but giving the option to go directly to a small voxel size with a huge mesh will crash Blender.

One approach would be to define the parameter relative to bounding box size or surface area. Displaying an estimated number of polygons based on surface area could also give users a hint about voxel size being set too low or high.

In general it's good to make the code robust to failed memory allocations, catching any exceptions or NULL returns from malloc as needed. This works to an extent, though the computer can still become very slow due to swapping. Ensuring the re-meshing takes up no more than e.g. half of RAM could guard against swapping, though may not be practical to implement.

Which quad extractor remesher are we going to support? Right now we have LibIGL/QEX in the branch, but Quadriflow should be better and with fewer dependencies. Can we develop a custom quad extractor remehser?

It seems worth trying Quadriflow. Implementing our own is hard, and if we do want to do this it may be better incrementally improve an existing implementation rather than doing it from scratch.

When vertex colors from sculpt mode are enabled, the brush texture should be interpreted as a color texture or as an alpha?

In texture paint mode there is a Texture for color and a Texture Mask, the latter more similar to the texture for sculpting and that's the one that would be shared between painting and sculpting. I imagine that you'd want to be able to specify both types of textures.

Right now the branch has a Paint Brush in sculpt mode, which only affects vertex colors, optimizing the undo operation. Should this be kept?

I guess this goes to the question of having all paint tools available along with sculpting, or if they should remain in separate modes. If underlying data structures are shared then switching modes should be fast at least, but from a UI perspective I'm not sure what's best.

If we port all the vertex paint tools to sculpt vertex colors we can leave the current vertex paint mode as an “attribute paint” mode for the everything nodes project. > For that kind of task, brush behavior and performance won’t be that important, and we are going to reuse a lot of code from sculpt mode. Can this option be considered?

We could, but I'm not sure it's that useful to have an attribute paint mode for face corner painting.

Other option could be keeping the current vertex paint mode while switching all the internals to sculpt vertex colors. The IU should be exactly the same, but internally you are going enter sculpt mode when selecting vertex paint. This also brings the advantages of more code reuse, better brushes, performance… but we may lose the ability to have a vertex color per face.

I think this is preferable.

Some filters, like smooth, require several iterations to be useful. Previewing this in real time would take an insane amount of memory. How can we solve this?

Why would this take a lot of memory? Is it because this it would be doing an undo push for every iteration? If so, successive smoothing operations could be combined into one step, similar to how we handle frame changes with OPTYPE_UNDO_GROUPED.

Real-time preview support for some filters may take a lot of resources. Should we add an option to apply the filter directly without the interactive preview? We can’t use the redo panel for the same reason, unless we add some kind of "update" button to it to apply the changes manually.

What is it about interactive preview that takes more resources than non-interactive operation?

Brecht Van Lommel (brecht) triaged this task as Normal priority.May 28 2019, 2:51 AM

Not sure I understand the question. If some mode does not use normal projection, it can display a cursor but without taking into account the normal?

Some users told me that they prefer the new cursor in texture paint mode, even if it does not match the projection. I personally think that we should wait to have proper support in those modes before making the cursor compatible.

If it's exactly 0.0 that does not produce any deformation, then we should not allow it to be set to that? If it's any small radius that is smaller than faces, then can't we have some fallback if not enough geometry is detected under the brush?
If it should be at the top level or not I guess depends if it's an option that you need to tweak often, ideally only for artistic control if it can be made to work well enough on different geometry.

The UI allows setting the strength to 0, which has the same effect. Setting the normal radius to 0 could be also considered an optimization, as it avoids doing any sampling and returns the normal of the face directly. I don't think normal radius is an option you want to change that often

What do you mean by "crease an edge while collapsing it"?

Some users reported that the scrape brush with a low normal radius produces artifacts near the hard surface edges when you are doing something like in the video. To achive that effect, you need a very evenly distributed topology, and if you are using dyntopo, you are breaking the edges of the model constantly due to the triangulation. I don't think that this is that important, but maybe we should not generate new geometry when using this brush from dyntopo.

Is this about saving memory in the undo stack, or is there some limitation in the undo code that makes this not work?

Both. The remeshing undo step is implemented in a similar way to the undo step that is done before entering dyntopo (it copies everything). For supporting redo, we would also need to copy the resulting mesh plus all the sculpting operations that were done on top of it. When working with high resolution meshes, this could take a lot of memory.

One approach would be to define the parameter relative to bounding box size or surface area. Displaying an estimated number of polygons based on surface area could also give users a hint about voxel size being set too low or high.

Estimating the number of polygons based on the surface area is a nice idea, I'm going to try that.

It seems worth trying Quadriflow. Implementing our own is hard, and if we do want to do this it may be better incrementally improve an existing implementation rather than doing it from scratch.

The only drawback that Quadriwflow has is that it does not take the mesh open edges into account, so it fails when remeshing planes or cloth. If we are able to solve that, the quad extractor remesher could be very decent.

Other option could be keeping the current vertex paint mode while switching all the internals to sculpt vertex colors. The IU should be exactly the same, but internally you are going enter sculpt mode when selecting vertex paint. This also brings the advantages of more code reuse, better brushes, performance… but we may lose the ability to have a vertex color per face.

I think this is preferable.

I also think this is the best option. I personally never used per-face colors or sculpting and painting at the same time. If we can replace the whole system internally, making it fully compatible with the render engines while keeping the UI mostly as it is now, it would be ideal. We can add an option for sculpting and painting at the same time only for the sculpt draw brush, just in case. That will also avoid adding painting code to all the sculpt brushes. If someone is working with vertex colors on a low poly mesh, he/she can always split the vertices.

Why would this take a lot of memory? Is it because this it would be doing an undo push for every iteration? If so, successive smoothing operations could be combined into one step, similar to how we handle frame changes with OPTYPE_UNDO_GROUPED.

Because I need to store the result of all intermediate iterations to avoid recalculating everything from the first to the last iteration while previewing the filter (the user may be adjusting the smooth filter between the 10th and the 11th iteration). I don't know if there is a better way to do this

What is it about interactive preview that takes more resources than non-interactive operation?

Updating and redrawing the whole mesh constantly. I implemented a way to filter the fully masked nodes before starting the filter to avoid updating and redrawing them, so it is possible to apply interactively a mesh filter operation in a small area of a high poly sculpt. This does not make sense with mask filters, so I need to redraw everything. Smoothing a whole sculpt or using the transform tool without masks are also common operations, and they are also extremely slow when used interactively.

xrg (xrg) added a subscriber: xrg (xrg).

@Pablo Dobarro (pablodp606)

Cursors:

We should handle cursors consistently in all paint & sculpt modes. In the paint modes, it would also be good to remove the arrow cursor by default and use something more appropriate like a crosshair or dot, with a cirfumference circle to communicate the brush size.

Remesh:

As we talked about, Blender already has some Remesh controls here:


These don't allow redo, which is fine - your remeshing could be added here and work similarly.

This is nicer, and less arbitrary than having a specific panel in obData just for this.

Sculpt Vertex colors:

As we discussed, I think we should keep Vertex Paint mode separate, but we could add an option in Sculpt mode for certain tools where it makes sense to also affect vertex colors.

I expect vertex colors would be most useful with Draw, Layer, Blob tools, but could also be added to Clay, Inflate and some others.

Transform pivots:

This could be a tool option, to only affect the pivot. As you say, it would work best if the gizmo would stay visible during transform, but that is wanted/needed in Blender in general anyway - best to solve this generically and not for this specific case.

Automasking:

I think yes, we should add masking tools for those things. There could also be a more obscure shortcut for people who want to works faster, but there should also be a more easily discoverable way to do this.

Remesh:

As we talked about, Blender already has some Remesh controls here:


These don't allow redo, which is fine - your remeshing could be added here and work similarly.
This is nicer, and less arbitrary than having a specific panel in obData just for this.

The voxel remesher also works in object mode, hence it's placement in the object data panel.
This is not exclusive to sculpt mode like dyntopo, so putting it under the dyntopo panel doesn't make much sense.
So yeah, ideally it should be on both places like the author said, a panel next to dyntopo and in the obect data panel as well.

Which brushes should support vertex colors?

How about all of them? Just like zbrush. 👍

Right now the branch has a Paint Brush in sculpt mode, which only affects vertex colors, optimizing the undo operation. Should this be kept?

Yes please.

Since N-panel now has tabs, why not to move there mesh, mask and color Filters instead of making them a Tool? It can be a tab wich is only visible when in sculpt mode. Maybe with value sliders which will be reseting themselfs to zero after use. Then will be possible to use Brush and having access to Filters at the same time.