UI: View-Facing Mesh Select Option #109357
|
@ -157,7 +157,7 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
|
|||
bl_context = ".mesh_edit" # dot on purpose (access from topbar)
|
||||
bl_label = "Options"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_ui_units_x = 12
|
||||
bl_ui_units_x = 13
|
||||
|
||||
def draw(self, _context):
|
||||
# layout = self.layout
|
||||
|
@ -210,6 +210,39 @@ class VIEW3D_PT_tools_meshedit_options_transform(View3DPanel, Panel):
|
|||
sub.prop(tool_settings, "double_threshold", text="Threshold")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_meshedit_options_viewport_facing_select(View3DPanel, Panel):
|
||||
bl_category = "Tool"
|
||||
bl_context = ".mesh_edit" # dot on purpose (access from topbar)
|
||||
bl_label = "Viewport Facing Select"
|
||||
bl_parent_id = "VIEW3D_PT_tools_meshedit_options"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_object
|
||||
|
||||
def draw_header(self, context):
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
self.layout.prop(tool_settings, "viewport_facing_select", text="", toggle=False)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = tool_settings.viewport_facing_select
|
||||
col.prop(tool_settings, "viewport_facing_select_mode")
|
||||
col.prop(tool_settings, "viewport_facing_select_threshold", text="Threshold")
|
||||
col.prop(tool_settings, "viewport_facing_select_vert")
|
||||
col.prop(tool_settings, "viewport_facing_select_edge")
|
||||
col.prop(tool_settings, "viewport_facing_select_face")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_meshedit_options_uvs(View3DPanel, Panel):
|
||||
bl_category = "Tool"
|
||||
bl_context = ".mesh_edit" # dot on purpose (access from topbar)
|
||||
|
@ -2374,6 +2407,7 @@ classes = (
|
|||
VIEW3D_PT_tools_object_options_transform,
|
||||
VIEW3D_PT_tools_meshedit_options,
|
||||
VIEW3D_PT_tools_meshedit_options_transform,
|
||||
VIEW3D_PT_tools_meshedit_options_viewport_facing_select,
|
||||
VIEW3D_PT_tools_meshedit_options_uvs,
|
||||
VIEW3D_PT_tools_armatureedit_options,
|
||||
VIEW3D_PT_tools_posemode_options,
|
||||
|
|
|
@ -377,6 +377,12 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
|
|||
if (idprop) {
|
||||
IDP_ClearProperty(idprop);
|
||||
}
|
||||
|
||||
/* Viewport-Facing Select */
|
||||
ts->viewport_facing_select_mode = 1;
|
||||
ts->viewport_facing_select_vert = 1;
|
||||
ts->viewport_facing_select_edge = 1;
|
||||
ts->viewport_facing_select_face = 1;
|
||||
}
|
||||
|
||||
void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
|
||||
|
|
|
@ -244,15 +244,217 @@ static void editselect_buf_cache_init_with_generic_userdata(wmGenericUserData *w
|
|||
/** \name Internal Edit-Mesh Utilities
|
||||
* \{ */
|
||||
|
||||
static bool edbm_backbuf_check_and_select_verts(EditSelectBuf_Cache *esel,
|
||||
void edbm_vert_orientation(const BMVert *eve, float normal[3], float plane[3], float meshmat[3][3])
|
||||
{
|
||||
float vec[3] = {0.0, 0.0, 0.0};
|
||||
float tangent[3] = {0.0f, 0.0f, 1.0f};
|
||||
copy_v3_v3(normal, eve->no);
|
||||
|
||||
if (eve->e) {
|
||||
float vert1v3[3] = {eve->e->v1->co[0], eve->e->v1->co[1], eve->e->v1->co[2]};
|
||||
float vert2v3[3] = {eve->e->v2->co[0], eve->e->v2->co[1], eve->e->v2->co[2]};
|
||||
sub_v3_v3v3(plane, vert2v3, vert1v3);
|
||||
}
|
||||
else {
|
||||
if (eve->no[0] < 0.5f) {
|
||||
vec[0] = 1.0f;
|
||||
}
|
||||
else if (eve->no[1] < 0.5f) {
|
||||
vec[1] = 1.0f;
|
||||
}
|
||||
else {
|
||||
vec[2] = 1.0f;
|
||||
}
|
||||
cross_v3_v3v3(plane, eve->no, vec);
|
||||
}
|
||||
normalize_v3(plane);
|
||||
copy_v3_v3(meshmat[2], normal);
|
||||
cross_v3_v3v3(meshmat[0], meshmat[2], tangent);
|
||||
|
||||
if (is_zero_v3(meshmat[0])) {
|
||||
tangent[0] = 1.0f;
|
||||
tangent[1] = tangent[2] = 0.0f;
|
||||
cross_v3_v3v3(meshmat[0], tangent, meshmat[2]);
|
||||
}
|
||||
cross_v3_v3v3(meshmat[1], meshmat[2], meshmat[0]);
|
||||
}
|
||||
|
||||
void edbm_edge_orientation(const BMEdge *eed, float normal[3], float plane[3], float meshmat[3][3])
|
||||
{
|
||||
float eed_plane[3] = {0.0, 0.0, 0.0};
|
||||
float vec[3] = {0.0, 0.0, 0.0};
|
||||
add_v3_v3v3(normal, eed->v1->no, eed->v2->no);
|
||||
sub_v3_v3v3(eed_plane, eed->v2->co, eed->v1->co);
|
||||
cross_v3_v3v3(vec, normal, eed_plane);
|
||||
cross_v3_v3v3(normal, eed_plane, vec);
|
||||
normalize_v3(normal);
|
||||
|
||||
if (BM_edge_is_boundary(eed)) {
|
||||
sub_v3_v3v3(plane, eed->l->v->co, eed->l->next->v->co);
|
||||
}
|
||||
else {
|
||||
if (eed->v2->co[1] > eed->v1->co[1]) {
|
||||
sub_v3_v3v3(plane, eed->v2->co, eed->v1->co);
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(plane, eed->v1->co, eed->v2->co);
|
||||
}
|
||||
}
|
||||
normalize_v3(plane);
|
||||
}
|
||||
|
||||
bool edbm_normal_facing_viewport(ViewContext *vc,
|
||||
struct BMVert *eve,
|
||||
struct BMEdge *eed,
|
||||
struct BMFace *efa,
|
||||
bool use_direction)
|
||||
{
|
||||
ToolSettings *ts = vc->scene->toolsettings;
|
||||
float normal[3] = {0, 0, 0};
|
||||
float plane[3] = {0, 0, 0};
|
||||
float meshcol3[3] = {0, 0, 0};
|
||||
float viewcol3[3] = {0, 0, 0};
|
||||
float meshmat[3][3] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int direction = eve != NULL ? ts->viewport_facing_select_vert :
|
||||
eed != NULL ? ts->viewport_facing_select_edge :
|
||||
ts->viewport_facing_select_face;
|
||||
bool backface = use_direction && (direction == 4 || direction == 8);
|
||||
|
||||
if (eve != NULL) {
|
||||
edbm_vert_orientation(eve, normal, plane, meshmat);
|
||||
}
|
||||
else {
|
||||
if (eed != NULL) {
|
||||
edbm_edge_orientation(eed, normal, plane, meshmat);
|
||||
}
|
||||
else if (efa != NULL) {
|
||||
copy_v3_v3(normal, efa->no);
|
||||
BM_face_calc_tangent_auto(efa, plane);
|
||||
}
|
||||
normalize_v3_v3(meshmat[2], normal);
|
||||
negate_v3_v3(meshmat[1], plane);
|
||||
|
||||
if (is_zero_v3(meshmat[1])) {
|
||||
meshmat[1][2] = 1.0f;
|
||||
}
|
||||
cross_v3_v3v3(meshmat[0], meshmat[2], meshmat[1]);
|
||||
cross_v3_v3v3(meshmat[1], meshmat[2], meshmat[0]);
|
||||
normalize_v3(meshmat[1]);
|
||||
}
|
||||
normalize_m3(meshmat);
|
||||
invert_m3(meshmat);
|
||||
meshcol3[0] = meshmat[0][2];
|
||||
meshcol3[1] = meshmat[1][2];
|
||||
meshcol3[2] = meshmat[2][2];
|
||||
viewcol3[0] = vc->rv3d->viewmat[0][2];
|
||||
viewcol3[1] = vc->rv3d->viewmat[1][2];
|
||||
viewcol3[2] = vc->rv3d->viewmat[2][2];
|
||||
|
||||
bool mesh_facing = false;
|
||||
if (backface) {
|
||||
mesh_facing = dot_v3v3(meshcol3, viewcol3) < -ts->viewport_facing_select_threshold;
|
||||
}
|
||||
else {
|
||||
mesh_facing = dot_v3v3(meshcol3, viewcol3) > ts->viewport_facing_select_threshold;
|
||||
}
|
||||
return mesh_facing;
|
||||
}
|
||||
|
||||
bool edbm_facing_viewport_precheck(ToolSettings *ts, int style, bool xray)
|
||||
{
|
||||
if (!ts->viewport_facing_select) {
|
||||
return false;
|
||||
}
|
||||
const bool mode_match = xray ? ts->viewport_facing_select_mode == 1 ||
|
||||
ts->viewport_facing_select_mode == 4 :
|
||||
ts->viewport_facing_select_mode < 4;
|
||||
const bool check_mesh_facing = mode_match && style > 0 && style < 16;
|
||||
return check_mesh_facing;
|
||||
}
|
||||
|
||||
bool edbm_facing_viewport(ViewContext *vc, BMVert *eve, BMEdge *eed, BMFace *efa, int style)
|
||||
{
|
||||
BMIter iter;
|
||||
bool mesh_facing = false;
|
||||
if (eve != NULL) {
|
||||
/* viewport-facing or rear-facing vert */
|
||||
mesh_facing = edbm_normal_facing_viewport(vc, eve, NULL, NULL, true);
|
||||
if (!mesh_facing && eve->e && eve->e->l && (style == 2 || style == 8)) {
|
||||
BM_ITER_ELEM (efa, &iter, eve, BM_FACES_OF_VERT) {
|
||||
const bool eve_efa_facing = edbm_normal_facing_viewport(vc, NULL, NULL, efa, false);
|
||||
/* vert of a viewport-facing face */
|
||||
if (style == 2) {
|
||||
if (eve_efa_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* vert of a rear-facing face */
|
||||
else if (!eve_efa_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (eed != NULL) {
|
||||
/* viewport-facing or rear-facing edge */
|
||||
mesh_facing = edbm_normal_facing_viewport(vc, NULL, eed, NULL, true);
|
||||
if (!mesh_facing && eed->l && (style == 2 || style == 8)) {
|
||||
BM_ITER_ELEM (efa, &iter, eed, BM_FACES_OF_EDGE) {
|
||||
const bool eed_efa_facing = edbm_normal_facing_viewport(vc, NULL, NULL, efa, false);
|
||||
/* edge of a viewport-facing face */
|
||||
if (style == 2) {
|
||||
if (eed_efa_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* edge of a rear-facing face */
|
||||
else if (!eed_efa_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (efa != NULL) {
|
||||
/* viewport-facing or rear-facing face */
|
||||
mesh_facing = edbm_normal_facing_viewport(vc, NULL, NULL, efa, true);
|
||||
if (!mesh_facing && (style == 2 || style == 8)) {
|
||||
BM_ITER_ELEM (eve, &iter, efa, BM_VERTS_OF_FACE) {
|
||||
const bool efa_eve_facing = edbm_normal_facing_viewport(vc, eve, NULL, NULL, false);
|
||||
/* face has a viewport-facing vert */
|
||||
if (style == 2) {
|
||||
if (efa_eve_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* face has a rear-facing vert */
|
||||
else if (!efa_eve_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return mesh_facing;
|
||||
}
|
||||
|
||||
static bool edbm_backbuf_check_and_select_verts(ViewContext *vc,
|
||||
EditSelectBuf_Cache *esel,
|
||||
Depsgraph *depsgraph,
|
||||
Object *ob,
|
||||
BMEditMesh *em,
|
||||
const eSelectOp sel_op)
|
||||
{
|
||||
ToolSettings *ts = vc->scene->toolsettings;
|
||||
BMVert *eve;
|
||||
BMIter iter;
|
||||
bool changed = false;
|
||||
const int style = ts->viewport_facing_select_vert;
|
||||
const bool check_mesh_facing = edbm_facing_viewport_precheck(ts, style, false);
|
||||
|
||||
const BLI_bitmap *select_bitmap = esel->select_bitmap;
|
||||
uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_VERTEX);
|
||||
|
@ -265,7 +467,12 @@ static bool edbm_backbuf_check_and_select_verts(EditSelectBuf_Cache *esel,
|
|||
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
|
||||
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
|
||||
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
|
||||
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && check_mesh_facing) {
|
||||
mesh_facing = edbm_facing_viewport(vc, eve, NULL, NULL, style);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_vert_select_set(em->bm, eve, sel_op_result);
|
||||
changed = true;
|
||||
|
@ -276,15 +483,19 @@ static bool edbm_backbuf_check_and_select_verts(EditSelectBuf_Cache *esel,
|
|||
return changed;
|
||||
}
|
||||
|
||||
static bool edbm_backbuf_check_and_select_edges(EditSelectBuf_Cache *esel,
|
||||
static bool edbm_backbuf_check_and_select_edges(ViewContext *vc,
|
||||
EditSelectBuf_Cache *esel,
|
||||
Depsgraph *depsgraph,
|
||||
Object *ob,
|
||||
BMEditMesh *em,
|
||||
const eSelectOp sel_op)
|
||||
{
|
||||
ToolSettings *ts = vc->scene->toolsettings;
|
||||
BMEdge *eed;
|
||||
BMIter iter;
|
||||
bool changed = false;
|
||||
const int style = ts->viewport_facing_select_edge;
|
||||
const bool check_mesh_facing = edbm_facing_viewport_precheck(ts, style, false);
|
||||
|
||||
const BLI_bitmap *select_bitmap = esel->select_bitmap;
|
||||
uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_EDGE);
|
||||
|
@ -297,7 +508,12 @@ static bool edbm_backbuf_check_and_select_edges(EditSelectBuf_Cache *esel,
|
|||
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
|
||||
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
|
||||
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
|
||||
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && check_mesh_facing) {
|
||||
mesh_facing = edbm_facing_viewport(vc, NULL, eed, NULL, style);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_edge_select_set(em->bm, eed, sel_op_result);
|
||||
changed = true;
|
||||
|
@ -308,15 +524,19 @@ static bool edbm_backbuf_check_and_select_edges(EditSelectBuf_Cache *esel,
|
|||
return changed;
|
||||
}
|
||||
|
||||
static bool edbm_backbuf_check_and_select_faces(EditSelectBuf_Cache *esel,
|
||||
static bool edbm_backbuf_check_and_select_faces(ViewContext *vc,
|
||||
EditSelectBuf_Cache *esel,
|
||||
Depsgraph *depsgraph,
|
||||
Object *ob,
|
||||
BMEditMesh *em,
|
||||
const eSelectOp sel_op)
|
||||
{
|
||||
ToolSettings *ts = vc->scene->toolsettings;
|
||||
BMFace *efa;
|
||||
BMIter iter;
|
||||
bool changed = false;
|
||||
const int style = ts->viewport_facing_select_face;
|
||||
const bool check_mesh_facing = edbm_facing_viewport_precheck(ts, style, false);
|
||||
|
||||
const BLI_bitmap *select_bitmap = esel->select_bitmap;
|
||||
uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_FACE);
|
||||
|
@ -329,7 +549,12 @@ static bool edbm_backbuf_check_and_select_faces(EditSelectBuf_Cache *esel,
|
|||
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
|
||||
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
|
||||
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
|
||||
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && check_mesh_facing) {
|
||||
mesh_facing = edbm_facing_viewport(vc, NULL, NULL, efa, style);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_face_select_set(em->bm, efa, sel_op_result);
|
||||
changed = true;
|
||||
|
@ -417,6 +642,7 @@ struct LassoSelectUserData {
|
|||
int mcoords_len;
|
||||
eSelectOp sel_op;
|
||||
eBezTriple_Flag select_flag;
|
||||
bool check_mesh_direction;
|
||||
|
||||
/* runtime */
|
||||
int pass;
|
||||
|
@ -719,7 +945,13 @@ static void do_lasso_select_mesh__doSelectVert(void *user_data,
|
|||
(BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
|
||||
BLI_lasso_is_point_inside(
|
||||
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, eve, NULL, NULL, data->vc->scene->toolsettings->viewport_facing_select_vert);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -752,7 +984,13 @@ static void do_lasso_select_mesh__doSelectEdge_pass0(void *user_data,
|
|||
data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), IS_CLIPPED) &&
|
||||
BLI_lasso_is_point_inside(
|
||||
data->mcoords, data->mcoords_len, UNPACK2(screen_co_b), IS_CLIPPED));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, eed, NULL, data->vc->scene->toolsettings->viewport_facing_select_edge);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||
data->is_done = true;
|
||||
|
@ -780,7 +1018,13 @@ static void do_lasso_select_mesh__doSelectEdge_pass1(void *user_data,
|
|||
UNPACK2(screen_co_a),
|
||||
UNPACK2(screen_co_b),
|
||||
IS_CLIPPED));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, eed, NULL, data->vc->scene->toolsettings->viewport_facing_select_edge);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -798,7 +1042,13 @@ static void do_lasso_select_mesh__doSelectFace(void *user_data,
|
|||
(BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
|
||||
BLI_lasso_is_point_inside(
|
||||
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, NULL, efa, data->vc->scene->toolsettings->viewport_facing_select_face);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -849,9 +1099,11 @@ static bool do_lasso_select_mesh(ViewContext *vc,
|
|||
if (ts->selectmode & SCE_SELECT_VERTEX) {
|
||||
if (use_zbuf) {
|
||||
data.is_changed |= edbm_backbuf_check_and_select_verts(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_vert, true);
|
||||
mesh_foreachScreenVert(
|
||||
vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
|
@ -867,6 +1119,14 @@ static bool do_lasso_select_mesh(ViewContext *vc,
|
|||
|
||||
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_NEAR |
|
||||
(use_zbuf ? (eV3DProjTest)0 : V3D_PROJ_TEST_CLIP_BB);
|
||||
if (use_zbuf) {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_edge, false);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_edge, true);
|
||||
}
|
||||
/* Fully inside. */
|
||||
mesh_foreachScreenEdge_clip_bb_segment(
|
||||
vc, do_lasso_select_mesh__doSelectEdge_pass0, &data_for_edge, clip_flag);
|
||||
|
@ -883,9 +1143,11 @@ static bool do_lasso_select_mesh(ViewContext *vc,
|
|||
if (ts->selectmode & SCE_SELECT_FACE) {
|
||||
if (use_zbuf) {
|
||||
data.is_changed |= edbm_backbuf_check_and_select_faces(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_face, true);
|
||||
mesh_foreachScreenFace(
|
||||
vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
|
@ -3457,6 +3719,7 @@ struct BoxSelectUserData {
|
|||
rctf _rect_fl;
|
||||
eSelectOp sel_op;
|
||||
eBezTriple_Flag select_flag;
|
||||
bool check_mesh_direction;
|
||||
|
||||
/* runtime */
|
||||
bool is_done;
|
||||
|
@ -3718,7 +3981,13 @@ static void do_mesh_box_select__doSelectVert(void *user_data,
|
|||
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(user_data);
|
||||
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
|
||||
const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, eve, NULL, NULL, data->vc->scene->toolsettings->viewport_facing_select_vert);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -3750,7 +4019,13 @@ static void do_mesh_box_select__doSelectEdge_pass0(void *user_data,
|
|||
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
|
||||
const bool is_inside = (is_visible &&
|
||||
edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, eed, NULL, data->vc->scene->toolsettings->viewport_facing_select_edge);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||
data->is_done = true;
|
||||
|
@ -3777,7 +4052,13 @@ static void do_mesh_box_select__doSelectEdge_pass1(void *user_data,
|
|||
|
||||
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
|
||||
const bool is_inside = (is_visible && edge_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, eed, NULL, data->vc->scene->toolsettings->viewport_facing_select_edge);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -3791,7 +4072,13 @@ static void do_mesh_box_select__doSelectFace(void *user_data,
|
|||
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(user_data);
|
||||
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
|
||||
const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, NULL, efa, data->vc->scene->toolsettings->viewport_facing_select_face);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -3834,9 +4121,11 @@ static bool do_mesh_box_select(ViewContext *vc,
|
|||
if (ts->selectmode & SCE_SELECT_VERTEX) {
|
||||
if (use_zbuf) {
|
||||
data.is_changed |= edbm_backbuf_check_and_select_verts(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_vert, true);
|
||||
mesh_foreachScreenVert(
|
||||
vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
|
@ -3852,6 +4141,14 @@ static bool do_mesh_box_select(ViewContext *vc,
|
|||
|
||||
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_NEAR |
|
||||
(use_zbuf ? (eV3DProjTest)0 : V3D_PROJ_TEST_CLIP_BB);
|
||||
if (use_zbuf) {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_edge, false);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_edge, true);
|
||||
}
|
||||
/* Fully inside. */
|
||||
mesh_foreachScreenEdge_clip_bb_segment(
|
||||
vc, do_mesh_box_select__doSelectEdge_pass0, &cb_data, clip_flag);
|
||||
|
@ -3868,9 +4165,11 @@ static bool do_mesh_box_select(ViewContext *vc,
|
|||
if (ts->selectmode & SCE_SELECT_FACE) {
|
||||
if (use_zbuf) {
|
||||
data.is_changed |= edbm_backbuf_check_and_select_faces(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_face, true);
|
||||
mesh_foreachScreenFace(
|
||||
vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
|
@ -4388,6 +4687,7 @@ struct CircleSelectUserData {
|
|||
float radius;
|
||||
float radius_squared;
|
||||
eBezTriple_Flag select_flag;
|
||||
bool check_mesh_direction;
|
||||
|
||||
/* runtime */
|
||||
bool is_changed;
|
||||
|
@ -4423,8 +4723,15 @@ static void mesh_circle_doSelectVert(void *user_data,
|
|||
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(user_data);
|
||||
|
||||
if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
|
||||
BM_vert_select_set(data->vc->em->bm, eve, data->select);
|
||||
data->is_changed = true;
|
||||
bool mesh_facing = true;
|
||||
if (data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, eve, NULL, NULL, data->vc->scene->toolsettings->viewport_facing_select_vert);
|
||||
}
|
||||
if (mesh_facing) {
|
||||
BM_vert_select_set(data->vc->em->bm, eve, data->select);
|
||||
data->is_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void mesh_circle_doSelectEdge(void *user_data,
|
||||
|
@ -4436,8 +4743,15 @@ static void mesh_circle_doSelectEdge(void *user_data,
|
|||
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(user_data);
|
||||
|
||||
if (edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, data->select);
|
||||
data->is_changed = true;
|
||||
bool mesh_facing = true;
|
||||
if (data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, eed, NULL, data->vc->scene->toolsettings->viewport_facing_select_edge);
|
||||
}
|
||||
if (mesh_facing) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, data->select);
|
||||
data->is_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void mesh_circle_doSelectFace(void *user_data,
|
||||
|
@ -4448,8 +4762,15 @@ static void mesh_circle_doSelectFace(void *user_data,
|
|||
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(user_data);
|
||||
|
||||
if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
|
||||
BM_face_select_set(data->vc->em->bm, efa, data->select);
|
||||
data->is_changed = true;
|
||||
bool mesh_facing = true;
|
||||
if (data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, NULL, efa, data->vc->scene->toolsettings->viewport_facing_select_face);
|
||||
}
|
||||
if (mesh_facing) {
|
||||
BM_face_select_set(data->vc->em->bm, efa, data->select);
|
||||
data->is_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4499,10 +4820,12 @@ static bool mesh_circle_select(ViewContext *vc,
|
|||
if (use_zbuf) {
|
||||
if (esel->select_bitmap != nullptr) {
|
||||
changed |= edbm_backbuf_check_and_select_verts(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
}
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_vert, true);
|
||||
mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
@ -4511,10 +4834,12 @@ static bool mesh_circle_select(ViewContext *vc,
|
|||
if (use_zbuf) {
|
||||
if (esel->select_bitmap != nullptr) {
|
||||
changed |= edbm_backbuf_check_and_select_edges(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
}
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_edge, true);
|
||||
mesh_foreachScreenEdge_clip_bb_segment(
|
||||
vc,
|
||||
mesh_circle_doSelectEdge,
|
||||
|
@ -4527,10 +4852,12 @@ static bool mesh_circle_select(ViewContext *vc,
|
|||
if (use_zbuf) {
|
||||
if (esel->select_bitmap != nullptr) {
|
||||
changed |= edbm_backbuf_check_and_select_faces(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
}
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_face, true);
|
||||
mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -398,6 +398,12 @@
|
|||
/* Placement */ \
|
||||
.snap_mode_tools = SCE_SNAP_TO_GEOM,\
|
||||
.plane_axis = 2,\
|
||||
\
|
||||
/* Viewport-Facing Select */ \
|
||||
.viewport_facing_select_mode = 1, \
|
||||
.viewport_facing_select_vert = 1, \
|
||||
.viewport_facing_select_edge = 1, \
|
||||
.viewport_facing_select_face = 1, \
|
||||
}
|
||||
|
||||
#define _DNA_DEFAULT_Sculpt \
|
||||
|
|
|
@ -1585,7 +1585,15 @@ typedef struct ToolSettings {
|
|||
char gpencil_v3d_align;
|
||||
/** General 2D Editor. */
|
||||
char gpencil_v2d_align;
|
||||
char _pad0[2];
|
||||
|
||||
/* Viewport-Facing Select */
|
||||
char viewport_facing_select;
|
||||
char viewport_facing_select_mode;
|
||||
char _pad0[1];
|
||||
float viewport_facing_select_threshold;
|
||||
char viewport_facing_select_vert;
|
||||
char viewport_facing_select_edge;
|
||||
char viewport_facing_select_face;
|
||||
|
||||
/* Annotations. */
|
||||
/** Stroke placement settings - 3D View. */
|
||||
|
@ -2421,6 +2429,40 @@ typedef enum eSnapTransformMode {
|
|||
SCE_SNAP_TRANSFORM_MODE_SCALE = (1 << 2),
|
||||
} eSnapTransformMode;
|
||||
|
||||
/** #ToolSettings.viewport_facing_mode */
|
||||
enum {
|
||||
VIEWPORT_FACING_SELECT_BOTH = (1 << 0),
|
||||
VIEWPORT_FACING_SELECT_NEAR = (1 << 1),
|
||||
VIEWPORT_FACING_SELECT_XRAY = (1 << 2),
|
||||
};
|
||||
|
||||
/** #ToolSettings.viewport_facing_select_vert */
|
||||
enum {
|
||||
VIEWPORT_FACING_SELECT_FRONT_VERTS = (1 << 0),
|
||||
VIEWPORT_FACING_SELECT_FRONT_VERTS_FACE = (1 << 1),
|
||||
VIEWPORT_FACING_SELECT_REAR_VERTS = (1 << 2),
|
||||
VIEWPORT_FACING_SELECT_REAR_VERTS_FACE = (1 << 3),
|
||||
VIEWPORT_FACING_SELECT_ALL_VERTS = (1 << 4),
|
||||
};
|
||||
|
||||
/** #ToolSettings.viewport_facing_select_edge */
|
||||
enum {
|
||||
VIEWPORT_FACING_SELECT_FRONT_EDGES = (1 << 0),
|
||||
VIEWPORT_FACING_SELECT_FRONT_EDGES_FACE = (1 << 1),
|
||||
VIEWPORT_FACING_SELECT_REAR_EDGES = (1 << 2),
|
||||
VIEWPORT_FACING_SELECT_REAR_EDGES_FACE = (1 << 3),
|
||||
VIEWPORT_FACING_SELECT_ALL_EDGES = (1 << 4),
|
||||
};
|
||||
|
||||
/** #ToolSettings.viewport_facing_select_face */
|
||||
enum {
|
||||
VIEWPORT_FACING_SELECT_FRONT_FACES = (1 << 0),
|
||||
VIEWPORT_FACING_SELECT_FRONT_FACES_VERT = (1 << 1),
|
||||
VIEWPORT_FACING_SELECT_REAR_FACES = (1 << 2),
|
||||
VIEWPORT_FACING_SELECT_REAR_FACES_VERT = (1 << 3),
|
||||
VIEWPORT_FACING_SELECT_ALL_FACES = (1 << 4),
|
||||
};
|
||||
|
||||
/** #ToolSettings::selectmode */
|
||||
enum {
|
||||
SCE_SELECT_VERTEX = 1 << 0, /* for mesh */
|
||||
|
|
|
@ -3101,6 +3101,108 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem viewport_facing_select_mode_items[] = {
|
||||
{VIEWPORT_FACING_SELECT_BOTH,
|
||||
"BOTH",
|
||||
0,
|
||||
"Near and X-Ray",
|
||||
"Use viewport-facing selection in near select and X-Ray"},
|
||||
{VIEWPORT_FACING_SELECT_NEAR,
|
||||
"NEAR",
|
||||
0,
|
||||
"Near",
|
||||
"Use viewport-facing selection in near select"},
|
||||
{VIEWPORT_FACING_SELECT_XRAY, "XRAY", 0, "X-Ray", "Use viewport-facing selection in X-Ray"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem viewport_facing_select_vert_items[] = {
|
||||
{VIEWPORT_FACING_SELECT_FRONT_VERTS,
|
||||
"FRONT_VERTS",
|
||||
0,
|
||||
"Front Verts",
|
||||
"Select vertices with viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_FRONT_VERTS_FACE,
|
||||
"FRONT_VERTS_FACE",
|
||||
0,
|
||||
"Verts of Front Face",
|
||||
"Select vertices if they are part of a face that has a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_VERTS,
|
||||
"REAR_VERTS",
|
||||
0,
|
||||
"Rear Verts",
|
||||
"Select vertices without viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_VERTS_FACE,
|
||||
"REAR_VERTS_FACE",
|
||||
0,
|
||||
"Verts of Rear Face",
|
||||
"Select vertices if they are part of a face that does not have a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_ALL_VERTS,
|
||||
"ALL_VERTS",
|
||||
0,
|
||||
"All Verts",
|
||||
"Select vertices regarless of their normal direction"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem viewport_facing_select_edge_items[] = {
|
||||
{VIEWPORT_FACING_SELECT_FRONT_EDGES,
|
||||
"FRONT_EDGES",
|
||||
0,
|
||||
"Front Edges",
|
||||
"Select edges with viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_FRONT_EDGES_FACE,
|
||||
"FRONT_EDGES_FACE",
|
||||
0,
|
||||
"Edges of Front Face",
|
||||
"Select edges if they are part of a face that has a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_EDGES,
|
||||
"REAR_EDGES",
|
||||
0,
|
||||
"Rear Edges",
|
||||
"Select edges without viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_EDGES_FACE,
|
||||
"REAR_EDGES_FACE",
|
||||
0,
|
||||
"Edges of Rear Face",
|
||||
"Select edges if they are part of a face that does not have a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_ALL_EDGES,
|
||||
"ALL_EDGES",
|
||||
0,
|
||||
"All Edges",
|
||||
"Select edges regarless of their normal direction"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem viewport_facing_select_face_items[] = {
|
||||
{VIEWPORT_FACING_SELECT_FRONT_FACES,
|
||||
"FRONT_FACES",
|
||||
0,
|
||||
"Front Faces",
|
||||
"Select faces with viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_FRONT_FACES_VERT,
|
||||
"FRONT_FACES_VERT",
|
||||
0,
|
||||
"Faces of Front Vert",
|
||||
"Select faces if they have a vertex with a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_FACES,
|
||||
"REAR_FACES",
|
||||
0,
|
||||
"Rear Faces",
|
||||
"Select faces without viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_FACES_VERT,
|
||||
"REAR_FACES_VERT",
|
||||
0,
|
||||
"Faces of Rear Vert",
|
||||
"Select faces if they have a vertex without a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_ALL_FACES,
|
||||
"ALL_FACES",
|
||||
0,
|
||||
"All Faces",
|
||||
"Select faces regarless of their normal direction"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "ToolSettings", nullptr);
|
||||
RNA_def_struct_path_func(srna, "rna_ToolSettings_path");
|
||||
RNA_def_struct_ui_text(srna, "Tool Settings", "");
|
||||
|
@ -3829,6 +3931,43 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Normal Vector", "Normal Vector used to copy, add or multiply");
|
||||
RNA_def_property_ui_range(prop, -10000.0, 10000.0, 1, 3);
|
||||
|
||||
/* Viewport-Facing Select */
|
||||
prop = RNA_def_property(srna, "viewport_facing_select", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "viewport_facing_select", 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Viewport Facing Select",
|
||||
"Filter box, lasso, and circle selection of mesh elements based on the direction of their "
|
||||
"normals compared to the viewport");
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_facing_select_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "viewport_facing_select_mode");
|
||||
RNA_def_property_enum_items(prop, viewport_facing_select_mode_items);
|
||||
RNA_def_property_ui_text(prop, "Mode", "Which selection modes to use viewport-facing selection");
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_facing_select_vert", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "viewport_facing_select_vert");
|
||||
RNA_def_property_enum_items(prop, viewport_facing_select_vert_items);
|
||||
RNA_def_property_ui_text(prop, "Vert", "Direction and mode for vertices");
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_facing_select_edge", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "viewport_facing_select_edge");
|
||||
RNA_def_property_enum_items(prop, viewport_facing_select_edge_items);
|
||||
RNA_def_property_ui_text(prop, "Edge", "Direction and mode for edges");
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_facing_select_face", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "viewport_facing_select_face");
|
||||
RNA_def_property_enum_items(prop, viewport_facing_select_face_items);
|
||||
RNA_def_property_ui_text(prop, "Face", "Direction and mode for faces");
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_facing_select_threshold", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, -0.999999, 0.999999);
|
||||
RNA_def_property_ui_range(prop, -0.999999, 0.999999, 1.0, 6);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Threshold",
|
||||
"How close the angles of the viewport and mesh element need to be for selection to occur");
|
||||
|
||||
/* Unified Paint Settings */
|
||||
prop = RNA_def_property(srna, "unified_paint_settings", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||
|
|
Loading…
Reference in New Issue