5
$\begingroup$

This question gets asked from time to time, and doesn't seem to get any attention. Here's one of the more recent instances: Converting a vertex group into a sculpt mask

I find it frustrating that the only way to create a sculpt mask in Blender is to manually paint it. This is needlessly imprecise in some situations, such as when there are already skeletal deformations in play which put various mesh parts too close together to get the brush between them to create the mask. Sure, you could return the armature to its rest pose, but some sculpt edits will require the new pose to be preserved, for the sake of reference.

Given that it is much easier to select multiple sub-elements (face/vertex/edge) precisely than to paint surfaces precisely, I would think there is a way to choose the former approach over the latter.

Is there?

$\endgroup$

3 Answers 3

8
$\begingroup$

I'm not great at sculpting, but what you can do is:

  1. Select faces in Edit Mode.
  2. Go to Sculpt Mode and from the Face Sets menu choose Face Set from Edit Mode Selection.
  3. Enable Options > Auto-Masking > Face Sets.

Now the Face Set is masked and your sculpt only affects the mesh outside of the mask. Maybe there is even a better way, I don't know if vertex groups with weight paint can be used for masking in Sculpt Mode, perhaps someone else can step in here. If so, you can set the weight according to the selection so this should also do what you want.

edit mode

create face set

enable auto-masking

sculpt

$\endgroup$
4
  • $\begingroup$ That works, but seems a bit fiddly for requiring the extra step that demands a face set be created after already having selected the faces. It also leads me to wonder what face sets are even for. They surely must have other uses than just creating masks. $\endgroup$
    – R-800
    Jan 25, 2022 at 13:22
  • $\begingroup$ Another issue, too, is that when using face sets, the mask behavior is different from what I am expecting. So long as you begin your stroke outside the face set, it is ignored as expected. But if you begin your stroke inside the face set, it is affected and everything outside of it is ignored. This could be desirable functionality, depending on the situation. But it should also be possible to ignore the masked region no matter where one is clicking. So far, all the options I've explored have not shown me how using face sets to create the mask can allow me to always ignore the masked region. $\endgroup$
    – R-800
    Jan 25, 2022 at 13:28
  • $\begingroup$ @R-800 About the extra step: I guess from selecting faces to a mask there will also be an extra step necessary even with a different method. A step that says "make mask from selection". Well, as I said I'm no expert in sculpting. I would usually use a mask to prevent me from accidentally sculpting where I don't want to sculpt, so I'm most of the time not starting my sculpt inside the mask. Of course that's not exactly how a "real" mask should work, at least you can use it with selected faces. But that's why I'm hoping someone else would come up with a better solution. $\endgroup$ Jan 25, 2022 at 14:24
  • $\begingroup$ I made an addon to do just that. I agree it is kind of stupid having to do it that way. blenderartists.org/t/kraynes-tools-free-addon-for-blender/…. It is the first module and first button on the tool panel it works by using "fill mask." Right now it is kind of wonky in 4.1 but it should work fine in 3.6+. I know this method is klugy, but I am working on a way to more directly set the sculpt mask from selection. $\endgroup$
    – Krayne
    Feb 25 at 10:22
5
$\begingroup$

For people interested in a scripted version. This will set every selected vert of the active object to the 'mask_value'

import bpy
import bmesh
import numpy as np
obj = bpy.context.active_object
bm = bmesh.new()
bm.from_mesh(obj.data)

#get selected verts
v_sel = np.empty(len(obj.data.vertices), dtype=bool)
obj.data.vertices.foreach_get('select', v_sel)
sel_idx, = np.where(v_sel)

#get custom data layer paint_mask
mask_layer= bm.verts.layers.paint_mask.verify() #strange way, but that gets you custom data layer
bm.verts.ensure_lookup_table()
#set every selected vert to mask_value

mask_value = 1.0
for idx in sel_idx:
    bm.verts[idx][mask_layer]=mask_value

bm.to_mesh(obj.data)
$\endgroup$
2
  • $\begingroup$ Thanks for the script, works like a charm! There's a little typo in its third line, though: "nummpy" instead of "numpy" 🙂 $\endgroup$ Sep 14, 2022 at 14:02
  • $\begingroup$ wow, it works :) $\endgroup$
    – barberik
    Jul 28, 2023 at 8:28
1
$\begingroup$

It appears that using the mask brush will also obey face sets, as long as the Face Sets and/or Face Set Boundary are selected when painting the mask.

Mask Options Menu

By enabling this, you can paint a masked area constricted by the face set. If you then disable the face set auto-masking you will have your typical masking behavior (where your brush obeys the mask no matter where the stroke starts).

This could also be useful for temporarily combining multiple face sets without destroying them.

I sympathize with OP that it would be great to have a "create face sets from vertex groups" option, but that doesn't account for the fact that vertex group selections can overlap while face sets cannot.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .