Fix T54686: objects don't occlude each other for edit-mesh select
This commit is contained in:
@@ -38,6 +38,7 @@ struct IDProperty;
|
|||||||
struct Main;
|
struct Main;
|
||||||
struct Material;
|
struct Material;
|
||||||
struct Object;
|
struct Object;
|
||||||
|
struct RegionView3D;
|
||||||
struct RenderEngine;
|
struct RenderEngine;
|
||||||
struct RenderEngineType;
|
struct RenderEngineType;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
@@ -135,6 +136,15 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
|
|||||||
void DRW_draw_depth_object(struct ARegion *ar,
|
void DRW_draw_depth_object(struct ARegion *ar,
|
||||||
struct GPUViewport *viewport,
|
struct GPUViewport *viewport,
|
||||||
struct Object *object);
|
struct Object *object);
|
||||||
|
void DRW_draw_select_id_object(struct Scene *scene,
|
||||||
|
struct RegionView3D *rv3d,
|
||||||
|
struct Object *ob,
|
||||||
|
short select_mode,
|
||||||
|
bool draw_facedot,
|
||||||
|
uint initial_offset,
|
||||||
|
uint *r_vert_offset,
|
||||||
|
uint *r_edge_offset,
|
||||||
|
uint *r_face_offset);
|
||||||
|
|
||||||
void DRW_framebuffer_select_id_setup(struct ARegion *ar, const bool clear);
|
void DRW_framebuffer_select_id_setup(struct ARegion *ar, const bool clear);
|
||||||
void DRW_framebuffer_select_id_release(struct ARegion *ar);
|
void DRW_framebuffer_select_id_release(struct ARegion *ar);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include "BKE_anim.h"
|
#include "BKE_anim.h"
|
||||||
#include "BKE_colortools.h"
|
#include "BKE_colortools.h"
|
||||||
#include "BKE_curve.h"
|
#include "BKE_curve.h"
|
||||||
|
#include "BKE_editmesh.h"
|
||||||
#include "BKE_global.h"
|
#include "BKE_global.h"
|
||||||
#include "BKE_gpencil.h"
|
#include "BKE_gpencil.h"
|
||||||
#include "BKE_lattice.h"
|
#include "BKE_lattice.h"
|
||||||
@@ -2615,6 +2616,12 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
|
|||||||
DRW_opengl_context_disable();
|
DRW_opengl_context_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** See #DRW_shgroup_world_clip_planes_from_rv3d. */
|
||||||
|
static void draw_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4])
|
||||||
|
{
|
||||||
|
GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the Depth Buffer and draws only the specified object.
|
* Clears the Depth Buffer and draws only the specified object.
|
||||||
*/
|
*/
|
||||||
@@ -2658,7 +2665,7 @@ void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object)
|
|||||||
GPU_SHADER_CFG_DEFAULT;
|
GPU_SHADER_CFG_DEFAULT;
|
||||||
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
|
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
|
||||||
if (world_clip_planes != NULL) {
|
if (world_clip_planes != NULL) {
|
||||||
GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
|
draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU_batch_draw(batch);
|
GPU_batch_draw(batch);
|
||||||
@@ -2678,6 +2685,203 @@ void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object)
|
|||||||
DRW_opengl_context_disable();
|
DRW_opengl_context_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void draw_mesh_verts(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
|
||||||
|
{
|
||||||
|
GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
|
||||||
|
|
||||||
|
const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
|
||||||
|
GPU_SHADER_CFG_DEFAULT;
|
||||||
|
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
|
||||||
|
GPU_batch_uniform_1ui(batch, "offset", offset);
|
||||||
|
if (world_clip_planes != NULL) {
|
||||||
|
draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
||||||
|
}
|
||||||
|
GPU_batch_draw(batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_mesh_edges(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
|
||||||
|
{
|
||||||
|
GPU_line_width(1.0f);
|
||||||
|
glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
|
||||||
|
|
||||||
|
const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
|
||||||
|
GPU_SHADER_CFG_DEFAULT;
|
||||||
|
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
|
||||||
|
GPU_batch_uniform_1ui(batch, "offset", offset);
|
||||||
|
if (world_clip_planes != NULL) {
|
||||||
|
draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
||||||
|
}
|
||||||
|
GPU_batch_draw(batch);
|
||||||
|
|
||||||
|
glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* two options, facecolors or black */
|
||||||
|
static void draw_mesh_face(GPUBatch *batch,
|
||||||
|
int offset,
|
||||||
|
const bool use_select,
|
||||||
|
const float world_clip_planes[6][4])
|
||||||
|
{
|
||||||
|
if (use_select) {
|
||||||
|
const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
|
||||||
|
GPU_SHADER_CFG_DEFAULT;
|
||||||
|
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
|
||||||
|
GPU_batch_uniform_1ui(batch, "offset", offset);
|
||||||
|
if (world_clip_planes != NULL) {
|
||||||
|
draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
||||||
|
}
|
||||||
|
GPU_batch_draw(batch);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
|
||||||
|
GPU_SHADER_CFG_DEFAULT;
|
||||||
|
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID, sh_cfg);
|
||||||
|
GPU_batch_uniform_1ui(batch, "id", 0);
|
||||||
|
if (world_clip_planes != NULL) {
|
||||||
|
draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
||||||
|
}
|
||||||
|
GPU_batch_draw(batch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_mesh_face_dot(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
|
||||||
|
{
|
||||||
|
const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
|
||||||
|
GPU_SHADER_CFG_DEFAULT;
|
||||||
|
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
|
||||||
|
GPU_batch_uniform_1ui(batch, "offset", offset);
|
||||||
|
if (world_clip_planes != NULL) {
|
||||||
|
draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
||||||
|
}
|
||||||
|
GPU_batch_draw(batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRW_draw_select_id_object(Scene *scene,
|
||||||
|
RegionView3D *rv3d,
|
||||||
|
Object *ob,
|
||||||
|
short select_mode,
|
||||||
|
bool draw_facedot,
|
||||||
|
uint initial_offset,
|
||||||
|
uint *r_vert_offset,
|
||||||
|
uint *r_edge_offset,
|
||||||
|
uint *r_face_offset)
|
||||||
|
{
|
||||||
|
ToolSettings *ts = scene->toolsettings;
|
||||||
|
if (select_mode == -1) {
|
||||||
|
select_mode = ts->selectmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
GPU_matrix_mul(ob->obmat);
|
||||||
|
GPU_depth_test(true);
|
||||||
|
|
||||||
|
const float(*world_clip_planes)[4] = NULL;
|
||||||
|
if (rv3d->rflag & RV3D_CLIPPING) {
|
||||||
|
ED_view3d_clipping_local(rv3d, ob->obmat);
|
||||||
|
world_clip_planes = rv3d->clip_local;
|
||||||
|
}
|
||||||
|
|
||||||
|
initial_offset += 1;
|
||||||
|
|
||||||
|
switch (ob->type) {
|
||||||
|
case OB_MESH:
|
||||||
|
if (ob->mode & OB_MODE_EDIT) {
|
||||||
|
Mesh *me = ob->data;
|
||||||
|
BMEditMesh *em = me->edit_mesh;
|
||||||
|
const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0;
|
||||||
|
|
||||||
|
DRW_mesh_batch_cache_validate(me);
|
||||||
|
|
||||||
|
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
|
||||||
|
|
||||||
|
GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots;
|
||||||
|
geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
|
||||||
|
if (select_mode & SCE_SELECT_EDGE) {
|
||||||
|
geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me);
|
||||||
|
}
|
||||||
|
if (select_mode & SCE_SELECT_VERTEX) {
|
||||||
|
geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
|
||||||
|
}
|
||||||
|
if (draw_facedot) {
|
||||||
|
geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me);
|
||||||
|
}
|
||||||
|
DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
|
||||||
|
|
||||||
|
draw_mesh_face(geom_faces, initial_offset, use_faceselect, world_clip_planes);
|
||||||
|
|
||||||
|
if (use_faceselect && draw_facedot) {
|
||||||
|
draw_mesh_face_dot(geom_facedots, initial_offset, world_clip_planes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (select_mode & SCE_SELECT_FACE) {
|
||||||
|
*r_face_offset = initial_offset + em->bm->totface;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*r_face_offset = initial_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
ED_view3d_polygon_offset(rv3d, 1.0);
|
||||||
|
|
||||||
|
/* Unlike faces, only draw edges if edge select mode. */
|
||||||
|
if (select_mode & SCE_SELECT_EDGE) {
|
||||||
|
draw_mesh_edges(geom_edges, *r_face_offset, world_clip_planes);
|
||||||
|
*r_edge_offset = *r_face_offset + em->bm->totedge;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Note that `r_vert_offset` is calculated from `r_edge_offset`.
|
||||||
|
* Otherwise the first vertex is never selected, see: T53512. */
|
||||||
|
*r_edge_offset = *r_face_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
ED_view3d_polygon_offset(rv3d, 1.1);
|
||||||
|
|
||||||
|
/* Unlike faces, only verts if vert select mode. */
|
||||||
|
if (select_mode & SCE_SELECT_VERTEX) {
|
||||||
|
draw_mesh_verts(geom_verts, *r_edge_offset, world_clip_planes);
|
||||||
|
*r_vert_offset = *r_edge_offset + em->bm->totvert;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*r_vert_offset = *r_edge_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
ED_view3d_polygon_offset(rv3d, 0.0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Mesh *me_orig = DEG_get_original_object(ob)->data;
|
||||||
|
Mesh *me_eval = ob->data;
|
||||||
|
|
||||||
|
DRW_mesh_batch_cache_validate(me_eval);
|
||||||
|
GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me_eval);
|
||||||
|
if ((me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) &&
|
||||||
|
/* Currently vertex select supports weight paint and vertex paint. */
|
||||||
|
((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) {
|
||||||
|
|
||||||
|
GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me_eval);
|
||||||
|
DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, true);
|
||||||
|
|
||||||
|
/* Only draw faces to mask out verts, we don't want their selection ID's. */
|
||||||
|
draw_mesh_face(geom_faces, 0, false, world_clip_planes);
|
||||||
|
draw_mesh_verts(geom_verts, 1, world_clip_planes);
|
||||||
|
|
||||||
|
*r_vert_offset = me_eval->totvert + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL);
|
||||||
|
DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, use_hide);
|
||||||
|
|
||||||
|
draw_mesh_face(geom_faces, initial_offset, true, world_clip_planes);
|
||||||
|
|
||||||
|
*r_face_offset = initial_offset + me_eval->totface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OB_CURVE:
|
||||||
|
case OB_SURF:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
GPU_matrix_set(rv3d->viewmat);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set an opengl context to be used with shaders that draw on U32 colors. */
|
/* Set an opengl context to be used with shaders that draw on U32 colors. */
|
||||||
void DRW_framebuffer_select_id_setup(ARegion *ar, const bool clear)
|
void DRW_framebuffer_select_id_setup(ARegion *ar, const bool clear)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -163,7 +163,10 @@ bool EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, short
|
|||||||
struct BMVert *EDBM_vert_find_nearest_ex(struct ViewContext *vc,
|
struct BMVert *EDBM_vert_find_nearest_ex(struct ViewContext *vc,
|
||||||
float *r_dist,
|
float *r_dist,
|
||||||
const bool use_select_bias,
|
const bool use_select_bias,
|
||||||
bool use_cycle);
|
bool use_cycle,
|
||||||
|
struct Base **bases,
|
||||||
|
uint bases_len,
|
||||||
|
uint *r_base_index);
|
||||||
struct BMVert *EDBM_vert_find_nearest(struct ViewContext *vc, float *r_dist);
|
struct BMVert *EDBM_vert_find_nearest(struct ViewContext *vc, float *r_dist);
|
||||||
|
|
||||||
struct BMEdge *EDBM_edge_find_nearest_ex(struct ViewContext *vc,
|
struct BMEdge *EDBM_edge_find_nearest_ex(struct ViewContext *vc,
|
||||||
@@ -171,7 +174,10 @@ struct BMEdge *EDBM_edge_find_nearest_ex(struct ViewContext *vc,
|
|||||||
float *r_dist_center,
|
float *r_dist_center,
|
||||||
const bool use_select_bias,
|
const bool use_select_bias,
|
||||||
const bool use_cycle,
|
const bool use_cycle,
|
||||||
struct BMEdge **r_eed_zbuf);
|
struct BMEdge **r_eed_zbuf,
|
||||||
|
struct Base **bases,
|
||||||
|
uint bases_len,
|
||||||
|
uint *r_base_index);
|
||||||
struct BMEdge *EDBM_edge_find_nearest(struct ViewContext *vc, float *r_dist);
|
struct BMEdge *EDBM_edge_find_nearest(struct ViewContext *vc, float *r_dist);
|
||||||
|
|
||||||
struct BMFace *EDBM_face_find_nearest_ex(struct ViewContext *vc,
|
struct BMFace *EDBM_face_find_nearest_ex(struct ViewContext *vc,
|
||||||
@@ -179,7 +185,10 @@ struct BMFace *EDBM_face_find_nearest_ex(struct ViewContext *vc,
|
|||||||
float *r_dist_center,
|
float *r_dist_center,
|
||||||
const bool use_select_bias,
|
const bool use_select_bias,
|
||||||
const bool use_cycle,
|
const bool use_cycle,
|
||||||
struct BMFace **r_efa_zbuf);
|
struct BMFace **r_efa_zbuf,
|
||||||
|
struct Base **bases,
|
||||||
|
uint bases_len,
|
||||||
|
uint *r_base_index);
|
||||||
struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, float *r_dist);
|
struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, float *r_dist);
|
||||||
|
|
||||||
bool EDBM_unified_findnearest(struct ViewContext *vc,
|
bool EDBM_unified_findnearest(struct ViewContext *vc,
|
||||||
@@ -230,6 +239,7 @@ void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc); /* rename
|
|||||||
bool EDBM_mesh_deselect_all_multi_ex(struct Base **bases, const uint bases_len);
|
bool EDBM_mesh_deselect_all_multi_ex(struct Base **bases, const uint bases_len);
|
||||||
bool EDBM_mesh_deselect_all_multi(struct bContext *C);
|
bool EDBM_mesh_deselect_all_multi(struct bContext *C);
|
||||||
|
|
||||||
|
/* Only use for modes that don't support multi-edit-modes (painting). */
|
||||||
extern unsigned int bm_vertoffs, bm_solidoffs, bm_wireoffs;
|
extern unsigned int bm_vertoffs, bm_solidoffs, bm_wireoffs;
|
||||||
|
|
||||||
/* editmesh_preselect_edgering.c */
|
/* editmesh_preselect_edgering.c */
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ set(INC
|
|||||||
../../blentranslation
|
../../blentranslation
|
||||||
../../bmesh
|
../../bmesh
|
||||||
../../depsgraph
|
../../depsgraph
|
||||||
|
../../draw
|
||||||
../../gpu
|
../../gpu
|
||||||
../../imbuf
|
../../imbuf
|
||||||
../../makesdna
|
../../makesdna
|
||||||
|
|||||||
@@ -461,13 +461,13 @@ bool do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MPoly *mpoly;
|
MPoly *mpoly;
|
||||||
uint *rt;
|
uint *rt, *buf, buf_len;
|
||||||
int a, index;
|
int a, index;
|
||||||
|
|
||||||
char *selar = MEM_callocN(me->totpoly + 1, "selar");
|
char *selar = MEM_callocN(me->totpoly + 1, "selar");
|
||||||
|
|
||||||
uint buf_len;
|
ED_view3d_select_id_validate(vc);
|
||||||
uint *buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
|
buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
|
||||||
|
|
||||||
rt = buf;
|
rt = buf;
|
||||||
|
|
||||||
|
|||||||
@@ -79,11 +79,11 @@ typedef struct RingSelOpData {
|
|||||||
|
|
||||||
Depsgraph *depsgraph;
|
Depsgraph *depsgraph;
|
||||||
|
|
||||||
Object **objects;
|
Base **bases;
|
||||||
uint objects_len;
|
uint bases_len;
|
||||||
|
|
||||||
/* These values switch objects based on the object under the cursor. */
|
/* These values switch objects based on the object under the cursor. */
|
||||||
uint ob_index;
|
uint base_index;
|
||||||
Object *ob;
|
Object *ob;
|
||||||
BMEditMesh *em;
|
BMEditMesh *em;
|
||||||
BMEdge *eed;
|
BMEdge *eed;
|
||||||
@@ -111,8 +111,8 @@ static void edgering_select(RingSelOpData *lcd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!lcd->extend) {
|
if (!lcd->extend) {
|
||||||
for (uint ob_index = 0; ob_index < lcd->objects_len; ob_index++) {
|
for (uint base_index = 0; base_index < lcd->bases_len; base_index++) {
|
||||||
Object *ob_iter = lcd->objects[ob_index];
|
Object *ob_iter = lcd->bases[base_index]->object;
|
||||||
BMEditMesh *em = BKE_editmesh_from_object(ob_iter);
|
BMEditMesh *em = BKE_editmesh_from_object(ob_iter);
|
||||||
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
||||||
DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
|
DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
|
||||||
@@ -252,7 +252,7 @@ static void ringsel_exit(bContext *UNUSED(C), wmOperator *op)
|
|||||||
|
|
||||||
EDBM_preselect_edgering_destroy(lcd->presel_edgering);
|
EDBM_preselect_edgering_destroy(lcd->presel_edgering);
|
||||||
|
|
||||||
MEM_freeN(lcd->objects);
|
MEM_freeN(lcd->bases);
|
||||||
|
|
||||||
ED_region_tag_redraw(lcd->ar);
|
ED_region_tag_redraw(lcd->ar);
|
||||||
|
|
||||||
@@ -307,21 +307,21 @@ static void ringcut_cancel(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void loopcut_update_edge(RingSelOpData *lcd,
|
static void loopcut_update_edge(RingSelOpData *lcd,
|
||||||
uint ob_index,
|
uint base_index,
|
||||||
BMEdge *e,
|
BMEdge *e,
|
||||||
const int previewlines)
|
const int previewlines)
|
||||||
{
|
{
|
||||||
if (e != lcd->eed) {
|
if (e != lcd->eed) {
|
||||||
lcd->eed = e;
|
lcd->eed = e;
|
||||||
lcd->ob = lcd->vc.obedit;
|
lcd->ob = lcd->vc.obedit;
|
||||||
lcd->ob_index = ob_index;
|
lcd->base_index = base_index;
|
||||||
lcd->em = lcd->vc.em;
|
lcd->em = lcd->vc.em;
|
||||||
ringsel_find_edge(lcd, previewlines);
|
ringsel_find_edge(lcd, previewlines);
|
||||||
}
|
}
|
||||||
else if (e == NULL) {
|
else if (e == NULL) {
|
||||||
lcd->ob = NULL;
|
lcd->ob = NULL;
|
||||||
lcd->em = NULL;
|
lcd->em = NULL;
|
||||||
lcd->ob_index = UINT_MAX;
|
lcd->base_index = UINT_MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,27 +331,26 @@ static void loopcut_mouse_move(RingSelOpData *lcd, const int previewlines)
|
|||||||
Object *ob;
|
Object *ob;
|
||||||
BMEdge *eed;
|
BMEdge *eed;
|
||||||
float dist;
|
float dist;
|
||||||
int ob_index;
|
int base_index;
|
||||||
} best = {
|
} best = {
|
||||||
.dist = ED_view3d_select_dist_px(),
|
.dist = ED_view3d_select_dist_px(),
|
||||||
};
|
};
|
||||||
|
|
||||||
for (uint ob_index = 0; ob_index < lcd->objects_len; ob_index++) {
|
uint base_index;
|
||||||
Object *ob_iter = lcd->objects[ob_index];
|
BMEdge *eed_test = EDBM_edge_find_nearest_ex(
|
||||||
ED_view3d_viewcontext_init_object(&lcd->vc, ob_iter);
|
&lcd->vc, &best.dist, NULL, false, false, NULL, lcd->bases, lcd->bases_len, &base_index);
|
||||||
BMEdge *eed_test = EDBM_edge_find_nearest_ex(&lcd->vc, &best.dist, NULL, false, false, NULL);
|
|
||||||
if (eed_test) {
|
if (eed_test) {
|
||||||
best.ob = ob_iter;
|
best.ob = lcd->bases[base_index]->object;
|
||||||
best.eed = eed_test;
|
best.eed = eed_test;
|
||||||
best.ob_index = ob_index;
|
best.base_index = base_index;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best.eed) {
|
if (best.eed) {
|
||||||
ED_view3d_viewcontext_init_object(&lcd->vc, best.ob);
|
ED_view3d_viewcontext_init_object(&lcd->vc, best.ob);
|
||||||
}
|
}
|
||||||
|
|
||||||
loopcut_update_edge(lcd, best.ob_index, best.eed, previewlines);
|
loopcut_update_edge(lcd, best.base_index, best.eed, previewlines);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called by both init() and exec() */
|
/* called by both init() and exec() */
|
||||||
@@ -361,22 +360,22 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
|
|||||||
|
|
||||||
/* Use for redo - intentionally wrap int to uint. */
|
/* Use for redo - intentionally wrap int to uint. */
|
||||||
const struct {
|
const struct {
|
||||||
uint ob_index;
|
uint base_index;
|
||||||
uint e_index;
|
uint e_index;
|
||||||
} exec_data = {
|
} exec_data = {
|
||||||
.ob_index = (uint)RNA_int_get(op->ptr, "object_index"),
|
.base_index = (uint)RNA_int_get(op->ptr, "object_index"),
|
||||||
.e_index = (uint)RNA_int_get(op->ptr, "edge_index"),
|
.e_index = (uint)RNA_int_get(op->ptr, "edge_index"),
|
||||||
};
|
};
|
||||||
|
|
||||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
|
|
||||||
uint objects_len;
|
uint bases_len;
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode(
|
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
|
||||||
view_layer, CTX_wm_view3d(C), &objects_len);
|
view_layer, CTX_wm_view3d(C), &bases_len);
|
||||||
|
|
||||||
if (is_interactive) {
|
if (is_interactive) {
|
||||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
||||||
Object *ob_iter = objects[ob_index];
|
Object *ob_iter = bases[base_index]->object;
|
||||||
if (modifiers_isDeformedByLattice(ob_iter) || modifiers_isDeformedByArmature(ob_iter)) {
|
if (modifiers_isDeformedByLattice(ob_iter) || modifiers_isDeformedByArmature(ob_iter)) {
|
||||||
BKE_report(
|
BKE_report(
|
||||||
op->reports, RPT_WARNING, "Loop cut does not work well on deformed edit mesh display");
|
op->reports, RPT_WARNING, "Loop cut does not work well on deformed edit mesh display");
|
||||||
@@ -390,12 +389,12 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
|
|||||||
/* for re-execution, check edge index is in range before we setup ringsel */
|
/* for re-execution, check edge index is in range before we setup ringsel */
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
if (is_interactive == false) {
|
if (is_interactive == false) {
|
||||||
if (exec_data.ob_index >= objects_len) {
|
if (exec_data.base_index >= bases_len) {
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Object *ob_iter = objects[exec_data.ob_index];
|
Object *ob_iter = bases[exec_data.base_index]->object;
|
||||||
BMEditMesh *em = BKE_editmesh_from_object(ob_iter);
|
BMEditMesh *em = BKE_editmesh_from_object(ob_iter);
|
||||||
if (exec_data.e_index >= em->bm->totedge) {
|
if (exec_data.e_index >= em->bm->totedge) {
|
||||||
ok = false;
|
ok = false;
|
||||||
@@ -404,7 +403,7 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ok || !ringsel_init(C, op, true)) {
|
if (!ok || !ringsel_init(C, op, true)) {
|
||||||
MEM_freeN(objects);
|
MEM_freeN(bases);
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,8 +415,8 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
|
|||||||
|
|
||||||
RingSelOpData *lcd = op->customdata;
|
RingSelOpData *lcd = op->customdata;
|
||||||
|
|
||||||
lcd->objects = objects;
|
lcd->bases = bases;
|
||||||
lcd->objects_len = objects_len;
|
lcd->bases_len = bases_len;
|
||||||
|
|
||||||
if (is_interactive) {
|
if (is_interactive) {
|
||||||
copy_v2_v2_int(lcd->vc.mval, event->mval);
|
copy_v2_v2_int(lcd->vc.mval, event->mval);
|
||||||
@@ -425,13 +424,13 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
Object *ob_iter = objects[exec_data.ob_index];
|
Object *ob_iter = bases[exec_data.base_index]->object;
|
||||||
ED_view3d_viewcontext_init_object(&lcd->vc, ob_iter);
|
ED_view3d_viewcontext_init_object(&lcd->vc, ob_iter);
|
||||||
|
|
||||||
BMEdge *e;
|
BMEdge *e;
|
||||||
BM_mesh_elem_table_ensure(lcd->vc.em->bm, BM_EDGE);
|
BM_mesh_elem_table_ensure(lcd->vc.em->bm, BM_EDGE);
|
||||||
e = BM_edge_at_index(lcd->vc.em->bm, exec_data.e_index);
|
e = BM_edge_at_index(lcd->vc.em->bm, exec_data.e_index);
|
||||||
loopcut_update_edge(lcd, exec_data.ob_index, e, 0);
|
loopcut_update_edge(lcd, exec_data.base_index, e, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_LOOPSLIDE_HACK
|
#ifdef USE_LOOPSLIDE_HACK
|
||||||
@@ -503,7 +502,7 @@ static int loopcut_finish(RingSelOpData *lcd, bContext *C, wmOperator *op)
|
|||||||
if (lcd->eed) {
|
if (lcd->eed) {
|
||||||
/* set for redo */
|
/* set for redo */
|
||||||
BM_mesh_elem_index_ensure(lcd->em->bm, BM_EDGE);
|
BM_mesh_elem_index_ensure(lcd->em->bm, BM_EDGE);
|
||||||
RNA_int_set(op->ptr, "object_index", lcd->ob_index);
|
RNA_int_set(op->ptr, "object_index", lcd->base_index);
|
||||||
RNA_int_set(op->ptr, "edge_index", BM_elem_index_get(lcd->eed));
|
RNA_int_set(op->ptr, "edge_index", BM_elem_index_get(lcd->eed));
|
||||||
|
|
||||||
/* execute */
|
/* execute */
|
||||||
|
|||||||
@@ -67,6 +67,8 @@
|
|||||||
#include "DEG_depsgraph.h"
|
#include "DEG_depsgraph.h"
|
||||||
#include "DEG_depsgraph_query.h"
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
|
#include "DRW_engine.h"
|
||||||
|
|
||||||
#include "mesh_intern.h" /* own include */
|
#include "mesh_intern.h" /* own include */
|
||||||
|
|
||||||
/* use bmesh operator flags for a few operators */
|
/* use bmesh operator flags for a few operators */
|
||||||
@@ -196,7 +198,87 @@ void EDBM_automerge(Scene *scene, Object *obedit, bool update, const char hflag)
|
|||||||
/** \name Back-Buffer OpenGL Selection
|
/** \name Back-Buffer OpenGL Selection
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
/* set in drawobject.c ... for colorindices */
|
struct EDBMBaseOffset {
|
||||||
|
uint face;
|
||||||
|
uint edge;
|
||||||
|
uint vert;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct EDBMBaseOffset *base_array_index_offsets = NULL;
|
||||||
|
|
||||||
|
static void edbm_select_pick_cache_alloc(uint bases_len)
|
||||||
|
{
|
||||||
|
BLI_assert(base_array_index_offsets == NULL);
|
||||||
|
base_array_index_offsets = MEM_mallocN(sizeof(struct EDBMBaseOffset) * bases_len, __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void edbm_select_pick_cache_free(void)
|
||||||
|
{
|
||||||
|
MEM_SAFE_FREE(base_array_index_offsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool check_ob_drawface_dot(short select_mode, View3D *vd, char dt)
|
||||||
|
{
|
||||||
|
if ((select_mode & SCE_SELECT_FACE) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if its drawing textures with zbuf sel, then don't draw dots */
|
||||||
|
if (dt == OB_TEXTURE && vd->shading.type == OB_TEXTURE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void edbm_select_pick_draw_bases(ViewContext *vc,
|
||||||
|
Base **bases,
|
||||||
|
uint bases_len,
|
||||||
|
short select_mode)
|
||||||
|
{
|
||||||
|
Scene *scene_eval = (Scene *)DEG_get_evaluated_id(vc->depsgraph, &vc->scene->id);
|
||||||
|
DRW_framebuffer_select_id_setup(vc->ar, true);
|
||||||
|
|
||||||
|
uint offset = 0;
|
||||||
|
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
||||||
|
Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, bases[base_index]->object);
|
||||||
|
struct EDBMBaseOffset *base_ofs = &base_array_index_offsets[base_index];
|
||||||
|
|
||||||
|
bool draw_facedot = check_ob_drawface_dot(select_mode, vc->v3d, ob_eval->dt);
|
||||||
|
|
||||||
|
DRW_draw_select_id_object(scene_eval,
|
||||||
|
vc->rv3d,
|
||||||
|
ob_eval,
|
||||||
|
select_mode,
|
||||||
|
draw_facedot,
|
||||||
|
offset,
|
||||||
|
&base_ofs->vert,
|
||||||
|
&base_ofs->edge,
|
||||||
|
&base_ofs->face);
|
||||||
|
|
||||||
|
offset = base_ofs->vert;
|
||||||
|
}
|
||||||
|
|
||||||
|
DRW_framebuffer_select_id_release(vc->ar);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint edbm_select_pick_base_index_find(uint bases_len, uint elem_index, uint *r_offset)
|
||||||
|
{
|
||||||
|
*r_offset = 0;
|
||||||
|
uint base_index = 0;
|
||||||
|
for (; base_index < bases_len; base_index++) {
|
||||||
|
struct EDBMBaseOffset *base_ofs = &base_array_index_offsets[base_index];
|
||||||
|
if (base_ofs->vert > elem_index) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*r_offset = base_ofs->vert;
|
||||||
|
}
|
||||||
|
|
||||||
|
*r_offset += 1;
|
||||||
|
return base_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set in view3d_draw_legacy.c ... for colorindices */
|
||||||
unsigned int bm_solidoffs = 0, bm_wireoffs = 0, bm_vertoffs = 0;
|
unsigned int bm_solidoffs = 0, bm_wireoffs = 0, bm_vertoffs = 0;
|
||||||
|
|
||||||
/* facilities for box select and circle select */
|
/* facilities for box select and circle select */
|
||||||
@@ -217,6 +299,7 @@ bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ED_view3d_select_id_validate(vc);
|
||||||
buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len);
|
buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len);
|
||||||
if ((buf == NULL) || (bm_vertoffs == 0)) {
|
if ((buf == NULL) || (bm_vertoffs == 0)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -303,6 +386,7 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ED_view3d_select_id_validate(vc);
|
||||||
buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len);
|
buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len);
|
||||||
if ((buf == NULL) || (bm_vertoffs == 0)) {
|
if ((buf == NULL) || (bm_vertoffs == 0)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -354,6 +438,8 @@ bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads)
|
|||||||
xmax = xs + rads;
|
xmax = xs + rads;
|
||||||
ymin = ys - rads;
|
ymin = ys - rads;
|
||||||
ymax = ys + rads;
|
ymax = ys + rads;
|
||||||
|
|
||||||
|
ED_view3d_select_id_validate(vc);
|
||||||
buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, NULL);
|
buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, NULL);
|
||||||
if ((buf == NULL) || (bm_vertoffs == 0)) {
|
if ((buf == NULL) || (bm_vertoffs == 0)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -470,29 +556,47 @@ static void findnearestvert__doClosest(void *userData,
|
|||||||
BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
|
BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
|
||||||
float *r_dist,
|
float *r_dist,
|
||||||
const bool use_select_bias,
|
const bool use_select_bias,
|
||||||
bool use_cycle)
|
bool use_cycle,
|
||||||
|
Base **bases,
|
||||||
|
uint bases_len,
|
||||||
|
uint *r_base_index)
|
||||||
{
|
{
|
||||||
BMesh *bm = vc->em->bm;
|
uint base_index = 0;
|
||||||
|
|
||||||
if (!XRAY_FLAG_ENABLED(vc->v3d)) {
|
if (!XRAY_FLAG_ENABLED(vc->v3d)) {
|
||||||
uint dist_px = (uint)ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist);
|
uint dist_px = (uint)ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist);
|
||||||
unsigned int index;
|
uint index, offset;
|
||||||
BMVert *eve;
|
BMVert *eve;
|
||||||
|
|
||||||
/* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
|
/* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
|
||||||
{
|
{
|
||||||
FAKE_SELECT_MODE_BEGIN (vc, fake_select_mode, select_mode, SCE_SELECT_VERTEX)
|
FAKE_SELECT_MODE_BEGIN (vc, fake_select_mode, select_mode, SCE_SELECT_VERTEX)
|
||||||
;
|
;
|
||||||
ED_view3d_select_id_validate_with_select_mode(vc, select_mode);
|
|
||||||
|
|
||||||
index = ED_view3d_select_id_read_nearest(vc, vc->mval, bm_wireoffs, 0xFFFFFF, &dist_px);
|
edbm_select_pick_cache_alloc(bases_len);
|
||||||
eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL;
|
edbm_select_pick_draw_bases(vc, bases, bases_len, select_mode);
|
||||||
|
|
||||||
|
index = ED_view3d_select_id_read_nearest(vc, vc->mval, 1, UINT_MAX, &dist_px);
|
||||||
|
|
||||||
|
if (index) {
|
||||||
|
base_index = edbm_select_pick_base_index_find(bases_len, index, &offset);
|
||||||
|
ED_view3d_viewcontext_init_object(vc, bases[base_index]->object);
|
||||||
|
eve = BM_vert_at_index_find_or_table(vc->em->bm, index - offset);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eve = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
edbm_select_pick_cache_free();
|
||||||
|
|
||||||
FAKE_SELECT_MODE_END(vc, fake_select_mode);
|
FAKE_SELECT_MODE_END(vc, fake_select_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eve) {
|
if (eve) {
|
||||||
if (dist_px < *r_dist) {
|
if (dist_px < *r_dist) {
|
||||||
|
if (r_base_index) {
|
||||||
|
*r_base_index = base_index;
|
||||||
|
}
|
||||||
*r_dist = dist_px;
|
*r_dist = dist_px;
|
||||||
return eve;
|
return eve;
|
||||||
}
|
}
|
||||||
@@ -509,7 +613,7 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
|
|||||||
|
|
||||||
if ((use_cycle == false) ||
|
if ((use_cycle == false) ||
|
||||||
(prev_select_elem &&
|
(prev_select_elem &&
|
||||||
(prev_select_elem != BM_vert_at_index_find_or_table(bm, prev_select_index)))) {
|
(prev_select_elem != BM_vert_at_index_find_or_table(vc->em->bm, prev_select_index)))) {
|
||||||
prev_select_index = 0;
|
prev_select_index = 0;
|
||||||
prev_select_elem = NULL;
|
prev_select_elem = NULL;
|
||||||
}
|
}
|
||||||
@@ -518,14 +622,26 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
|
|||||||
data.mval_fl[1] = vc->mval[1];
|
data.mval_fl[1] = vc->mval[1];
|
||||||
data.use_select_bias = use_select_bias;
|
data.use_select_bias = use_select_bias;
|
||||||
data.use_cycle = use_cycle;
|
data.use_cycle = use_cycle;
|
||||||
data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist;
|
|
||||||
data.cycle_index_prev = prev_select_index;
|
data.cycle_index_prev = prev_select_index;
|
||||||
|
|
||||||
|
for (; base_index < bases_len; base_index++) {
|
||||||
|
Base *base_iter = bases[base_index];
|
||||||
|
ED_view3d_viewcontext_init_object(vc, base_iter->object);
|
||||||
|
data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
|
||||||
|
*r_dist;
|
||||||
|
|
||||||
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
|
||||||
mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, clip_flag);
|
mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, clip_flag);
|
||||||
|
|
||||||
hit = (data.use_cycle && data.hit_cycle.vert) ? &data.hit_cycle : &data.hit;
|
hit = (data.use_cycle && data.hit_cycle.vert) ? &data.hit_cycle : &data.hit;
|
||||||
|
|
||||||
|
if (hit->dist < *r_dist) {
|
||||||
|
if (r_base_index) {
|
||||||
|
*r_base_index = base_index;
|
||||||
|
}
|
||||||
*r_dist = hit->dist;
|
*r_dist = hit->dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
prev_select_elem = hit->vert;
|
prev_select_elem = hit->vert;
|
||||||
prev_select_index = hit->index;
|
prev_select_index = hit->index;
|
||||||
@@ -536,7 +652,8 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
|
|||||||
|
|
||||||
BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist)
|
BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist)
|
||||||
{
|
{
|
||||||
return EDBM_vert_find_nearest_ex(vc, r_dist, false, false);
|
Base *base = BKE_view_layer_base_find(vc->view_layer, vc->obact);
|
||||||
|
return EDBM_vert_find_nearest_ex(vc, r_dist, false, false, &base, 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the distance to the edge we already have */
|
/* find the distance to the edge we already have */
|
||||||
@@ -659,23 +776,38 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
|
|||||||
float *r_dist_center,
|
float *r_dist_center,
|
||||||
const bool use_select_bias,
|
const bool use_select_bias,
|
||||||
const bool use_cycle,
|
const bool use_cycle,
|
||||||
BMEdge **r_eed_zbuf)
|
BMEdge **r_eed_zbuf,
|
||||||
|
Base **bases,
|
||||||
|
uint bases_len,
|
||||||
|
uint *r_base_index)
|
||||||
{
|
{
|
||||||
BMesh *bm = vc->em->bm;
|
uint base_index = 0;
|
||||||
|
|
||||||
if (!XRAY_FLAG_ENABLED(vc->v3d)) {
|
if (!XRAY_FLAG_ENABLED(vc->v3d)) {
|
||||||
uint dist_px = (uint)ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist);
|
uint dist_px = (uint)ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist);
|
||||||
unsigned int index;
|
uint index, offset;
|
||||||
BMEdge *eed;
|
BMEdge *eed;
|
||||||
|
|
||||||
/* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
|
/* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
|
||||||
{
|
{
|
||||||
FAKE_SELECT_MODE_BEGIN (vc, fake_select_mode, select_mode, SCE_SELECT_EDGE)
|
FAKE_SELECT_MODE_BEGIN (vc, fake_select_mode, select_mode, SCE_SELECT_EDGE)
|
||||||
;
|
;
|
||||||
ED_view3d_select_id_validate_with_select_mode(vc, select_mode);
|
|
||||||
|
|
||||||
index = ED_view3d_select_id_read_nearest(vc, vc->mval, bm_solidoffs, bm_wireoffs, &dist_px);
|
edbm_select_pick_cache_alloc(bases_len);
|
||||||
eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL;
|
edbm_select_pick_draw_bases(vc, bases, bases_len, select_mode);
|
||||||
|
|
||||||
|
index = ED_view3d_select_id_read_nearest(vc, vc->mval, 1, UINT_MAX, &dist_px);
|
||||||
|
|
||||||
|
if (index) {
|
||||||
|
base_index = edbm_select_pick_base_index_find(bases_len, index, &offset);
|
||||||
|
ED_view3d_viewcontext_init_object(vc, bases[base_index]->object);
|
||||||
|
eed = BM_edge_at_index_find_or_table(vc->em->bm, index - offset);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eed = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
edbm_select_pick_cache_free();
|
||||||
|
|
||||||
FAKE_SELECT_MODE_END(vc, fake_select_mode);
|
FAKE_SELECT_MODE_END(vc, fake_select_mode);
|
||||||
}
|
}
|
||||||
@@ -704,6 +836,9 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
|
|||||||
|
|
||||||
if (eed) {
|
if (eed) {
|
||||||
if (dist_px < *r_dist) {
|
if (dist_px < *r_dist) {
|
||||||
|
if (r_base_index) {
|
||||||
|
*r_base_index = base_index;
|
||||||
|
}
|
||||||
*r_dist = dist_px;
|
*r_dist = dist_px;
|
||||||
return eed;
|
return eed;
|
||||||
}
|
}
|
||||||
@@ -721,7 +856,7 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
|
|||||||
|
|
||||||
if ((use_cycle == false) ||
|
if ((use_cycle == false) ||
|
||||||
(prev_select_elem &&
|
(prev_select_elem &&
|
||||||
(prev_select_elem != BM_edge_at_index_find_or_table(bm, prev_select_index)))) {
|
(prev_select_elem != BM_edge_at_index_find_or_table(vc->em->bm, prev_select_index)))) {
|
||||||
prev_select_index = 0;
|
prev_select_index = 0;
|
||||||
prev_select_elem = NULL;
|
prev_select_elem = NULL;
|
||||||
}
|
}
|
||||||
@@ -731,14 +866,27 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
|
|||||||
data.mval_fl[1] = vc->mval[1];
|
data.mval_fl[1] = vc->mval[1];
|
||||||
data.use_select_bias = use_select_bias;
|
data.use_select_bias = use_select_bias;
|
||||||
data.use_cycle = use_cycle;
|
data.use_cycle = use_cycle;
|
||||||
data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist;
|
|
||||||
data.cycle_index_prev = prev_select_index;
|
data.cycle_index_prev = prev_select_index;
|
||||||
|
|
||||||
|
for (; base_index < bases_len; base_index++) {
|
||||||
|
Base *base_iter = bases[base_index];
|
||||||
|
ED_view3d_viewcontext_init_object(vc, base_iter->object);
|
||||||
|
data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
|
||||||
|
*r_dist;
|
||||||
|
|
||||||
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
|
||||||
mesh_foreachScreenEdge(vc, find_nearest_edge__doClosest, &data, clip_flag);
|
mesh_foreachScreenEdge(vc, find_nearest_edge__doClosest, &data, clip_flag);
|
||||||
|
|
||||||
hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle : &data.hit;
|
hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle : &data.hit;
|
||||||
|
|
||||||
|
if (hit->dist < *r_dist) {
|
||||||
|
if (r_base_index) {
|
||||||
|
*r_base_index = base_index;
|
||||||
|
}
|
||||||
*r_dist = hit->dist;
|
*r_dist = hit->dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (r_dist_center) {
|
if (r_dist_center) {
|
||||||
*r_dist_center = hit->dist_center;
|
*r_dist_center = hit->dist_center;
|
||||||
}
|
}
|
||||||
@@ -752,7 +900,8 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
|
|||||||
|
|
||||||
BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist)
|
BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist)
|
||||||
{
|
{
|
||||||
return EDBM_edge_find_nearest_ex(vc, r_dist, NULL, false, false, NULL);
|
Base *base = BKE_view_layer_base_find(vc->view_layer, vc->obact);
|
||||||
|
return EDBM_edge_find_nearest_ex(vc, r_dist, NULL, false, false, NULL, &base, 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the distance to the face we already have */
|
/* find the distance to the face we already have */
|
||||||
@@ -832,22 +981,37 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
|
|||||||
float *r_dist_center,
|
float *r_dist_center,
|
||||||
const bool use_select_bias,
|
const bool use_select_bias,
|
||||||
const bool use_cycle,
|
const bool use_cycle,
|
||||||
BMFace **r_efa_zbuf)
|
BMFace **r_efa_zbuf,
|
||||||
|
Base **bases,
|
||||||
|
uint bases_len,
|
||||||
|
uint *r_base_index)
|
||||||
{
|
{
|
||||||
BMesh *bm = vc->em->bm;
|
uint base_index = 0;
|
||||||
|
|
||||||
if (!XRAY_FLAG_ENABLED(vc->v3d)) {
|
if (!XRAY_FLAG_ENABLED(vc->v3d)) {
|
||||||
float dist_test = 0.0f;
|
float dist_test = 0.0f;
|
||||||
unsigned int index;
|
uint index, offset;
|
||||||
BMFace *efa;
|
BMFace *efa;
|
||||||
|
|
||||||
{
|
{
|
||||||
FAKE_SELECT_MODE_BEGIN (vc, fake_select_mode, select_mode, SCE_SELECT_FACE)
|
FAKE_SELECT_MODE_BEGIN (vc, fake_select_mode, select_mode, SCE_SELECT_FACE)
|
||||||
;
|
;
|
||||||
ED_view3d_select_id_validate_with_select_mode(vc, select_mode);
|
|
||||||
|
edbm_select_pick_cache_alloc(bases_len);
|
||||||
|
edbm_select_pick_draw_bases(vc, bases, bases_len, select_mode);
|
||||||
|
|
||||||
index = ED_view3d_select_id_sample(vc, vc->mval[0], vc->mval[1]);
|
index = ED_view3d_select_id_sample(vc, vc->mval[0], vc->mval[1]);
|
||||||
efa = index ? BM_face_at_index_find_or_table(bm, index - 1) : NULL;
|
|
||||||
|
if (index) {
|
||||||
|
base_index = edbm_select_pick_base_index_find(bases_len, index, &offset);
|
||||||
|
ED_view3d_viewcontext_init_object(vc, bases[base_index]->object);
|
||||||
|
efa = BM_face_at_index_find_or_table(vc->em->bm, index - offset);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
efa = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
edbm_select_pick_cache_free();
|
||||||
|
|
||||||
FAKE_SELECT_MODE_END(vc, fake_select_mode);
|
FAKE_SELECT_MODE_END(vc, fake_select_mode);
|
||||||
}
|
}
|
||||||
@@ -876,6 +1040,9 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
|
|||||||
|
|
||||||
if (efa) {
|
if (efa) {
|
||||||
if (dist_test < *r_dist) {
|
if (dist_test < *r_dist) {
|
||||||
|
if (r_base_index) {
|
||||||
|
*r_base_index = base_index;
|
||||||
|
}
|
||||||
*r_dist = dist_test;
|
*r_dist = dist_test;
|
||||||
return efa;
|
return efa;
|
||||||
}
|
}
|
||||||
@@ -892,7 +1059,7 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
|
|||||||
|
|
||||||
if ((use_cycle == false) ||
|
if ((use_cycle == false) ||
|
||||||
(prev_select_elem &&
|
(prev_select_elem &&
|
||||||
(prev_select_elem != BM_face_at_index_find_or_table(bm, prev_select_index)))) {
|
(prev_select_elem != BM_face_at_index_find_or_table(vc->em->bm, prev_select_index)))) {
|
||||||
prev_select_index = 0;
|
prev_select_index = 0;
|
||||||
prev_select_elem = NULL;
|
prev_select_elem = NULL;
|
||||||
}
|
}
|
||||||
@@ -901,14 +1068,28 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
|
|||||||
data.mval_fl[1] = vc->mval[1];
|
data.mval_fl[1] = vc->mval[1];
|
||||||
data.use_select_bias = use_select_bias;
|
data.use_select_bias = use_select_bias;
|
||||||
data.use_cycle = use_cycle;
|
data.use_cycle = use_cycle;
|
||||||
data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist;
|
|
||||||
data.cycle_index_prev = prev_select_index;
|
data.cycle_index_prev = prev_select_index;
|
||||||
|
|
||||||
|
for (; base_index < bases_len; base_index++) {
|
||||||
|
Base *base_iter = bases[base_index];
|
||||||
|
ED_view3d_viewcontext_init_object(vc, base_iter->object);
|
||||||
|
|
||||||
|
data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
|
||||||
|
*r_dist;
|
||||||
|
|
||||||
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
|
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
|
||||||
mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, clip_flag);
|
mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, clip_flag);
|
||||||
|
|
||||||
hit = (data.use_cycle && data.hit_cycle.face) ? &data.hit_cycle : &data.hit;
|
hit = (data.use_cycle && data.hit_cycle.face) ? &data.hit_cycle : &data.hit;
|
||||||
|
|
||||||
|
if (hit->dist < *r_dist) {
|
||||||
|
if (r_base_index) {
|
||||||
|
*r_base_index = base_index;
|
||||||
|
}
|
||||||
*r_dist = hit->dist;
|
*r_dist = hit->dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (r_dist_center) {
|
if (r_dist_center) {
|
||||||
*r_dist_center = hit->dist;
|
*r_dist_center = hit->dist;
|
||||||
}
|
}
|
||||||
@@ -922,7 +1103,8 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
|
|||||||
|
|
||||||
BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
|
BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
|
||||||
{
|
{
|
||||||
return EDBM_face_find_nearest_ex(vc, r_dist, NULL, false, false, NULL);
|
Base *base = BKE_view_layer_base_find(vc->view_layer, vc->obact);
|
||||||
|
return EDBM_face_find_nearest_ex(vc, r_dist, NULL, false, false, NULL, &base, 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef FIND_NEAR_SELECT_BIAS
|
#undef FIND_NEAR_SELECT_BIAS
|
||||||
@@ -965,25 +1147,20 @@ static bool unified_findnearest(ViewContext *vc,
|
|||||||
} f, f_zbuf;
|
} f, f_zbuf;
|
||||||
} hit = {{NULL}};
|
} hit = {{NULL}};
|
||||||
|
|
||||||
/* TODO(campbell): perform selection as one pass
|
|
||||||
* instead of many smaller passes (which doesn't work for zbuf occlusion). */
|
|
||||||
|
|
||||||
/* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
|
/* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
|
||||||
|
short selectmode = vc->scene->toolsettings->selectmode;
|
||||||
|
|
||||||
if ((dist > 0.0f) && em->selectmode & SCE_SELECT_FACE) {
|
if ((dist > 0.0f) && (selectmode & SCE_SELECT_FACE)) {
|
||||||
float dist_center = 0.0f;
|
float dist_center = 0.0f;
|
||||||
float *dist_center_p = (em->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_VERTEX)) ?
|
float *dist_center_p = (em->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_VERTEX)) ?
|
||||||
&dist_center :
|
&dist_center :
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
uint base_index = 0;
|
||||||
Base *base_iter = bases[base_index];
|
|
||||||
Object *obedit = base_iter->object;
|
|
||||||
ED_view3d_viewcontext_init_object(vc, obedit);
|
|
||||||
BLI_assert(vc->em->selectmode == em->selectmode);
|
|
||||||
BMFace *efa_zbuf = NULL;
|
BMFace *efa_zbuf = NULL;
|
||||||
BMFace *efa_test = EDBM_face_find_nearest_ex(
|
BMFace *efa_test = EDBM_face_find_nearest_ex(
|
||||||
vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf);
|
vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf, bases, bases_len, &base_index);
|
||||||
|
|
||||||
if (efa_test && dist_center_p) {
|
if (efa_test && dist_center_p) {
|
||||||
dist = min_ff(dist_margin, dist_center);
|
dist = min_ff(dist_margin, dist_center);
|
||||||
}
|
}
|
||||||
@@ -995,20 +1172,17 @@ static bool unified_findnearest(ViewContext *vc,
|
|||||||
hit.f_zbuf.base_index = base_index;
|
hit.f_zbuf.base_index = base_index;
|
||||||
hit.f_zbuf.ele = efa_zbuf;
|
hit.f_zbuf.ele = efa_zbuf;
|
||||||
}
|
}
|
||||||
} /* bases */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dist > 0.0f) && (em->selectmode & SCE_SELECT_EDGE)) {
|
if ((dist > 0.0f) && (selectmode & SCE_SELECT_EDGE)) {
|
||||||
float dist_center = 0.0f;
|
float dist_center = 0.0f;
|
||||||
float *dist_center_p = (em->selectmode & SCE_SELECT_VERTEX) ? &dist_center : NULL;
|
float *dist_center_p = (em->selectmode & SCE_SELECT_VERTEX) ? &dist_center : NULL;
|
||||||
|
|
||||||
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
uint base_index = 0;
|
||||||
Base *base_iter = bases[base_index];
|
|
||||||
Object *obedit = base_iter->object;
|
|
||||||
ED_view3d_viewcontext_init_object(vc, obedit);
|
|
||||||
BMEdge *eed_zbuf = NULL;
|
BMEdge *eed_zbuf = NULL;
|
||||||
BMEdge *eed_test = EDBM_edge_find_nearest_ex(
|
BMEdge *eed_test = EDBM_edge_find_nearest_ex(
|
||||||
vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf);
|
vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf, bases, bases_len, &base_index);
|
||||||
|
|
||||||
if (eed_test && dist_center_p) {
|
if (eed_test && dist_center_p) {
|
||||||
dist = min_ff(dist_margin, dist_center);
|
dist = min_ff(dist_margin, dist_center);
|
||||||
}
|
}
|
||||||
@@ -1020,20 +1194,17 @@ static bool unified_findnearest(ViewContext *vc,
|
|||||||
hit.e_zbuf.base_index = base_index;
|
hit.e_zbuf.base_index = base_index;
|
||||||
hit.e_zbuf.ele = eed_zbuf;
|
hit.e_zbuf.ele = eed_zbuf;
|
||||||
}
|
}
|
||||||
} /* bases */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dist > 0.0f) && em->selectmode & SCE_SELECT_VERTEX) {
|
if ((dist > 0.0f) && (selectmode & SCE_SELECT_VERTEX)) {
|
||||||
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
uint base_index = 0;
|
||||||
Base *base_iter = bases[base_index];
|
BMVert *eve_test = EDBM_vert_find_nearest_ex(
|
||||||
Object *obedit = base_iter->object;
|
vc, &dist, true, use_cycle, bases, bases_len, &base_index);
|
||||||
ED_view3d_viewcontext_init_object(vc, obedit);
|
|
||||||
BMVert *eve_test = EDBM_vert_find_nearest_ex(vc, &dist, true, use_cycle);
|
|
||||||
if (eve_test) {
|
if (eve_test) {
|
||||||
hit.v.base_index = base_index;
|
hit.v.base_index = base_index;
|
||||||
hit.v.ele = eve_test;
|
hit.v.ele = eve_test;
|
||||||
}
|
}
|
||||||
} /* bases */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return only one of 3 pointers, for frontbuffer redraws */
|
/* return only one of 3 pointers, for frontbuffer redraws */
|
||||||
|
|||||||
@@ -1109,13 +1109,11 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], uint dist_px,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ED_view3d_viewcontext_init(C, &vc);
|
ED_view3d_viewcontext_init(C, &vc);
|
||||||
|
ED_view3d_select_id_validate(&vc);
|
||||||
|
|
||||||
if (dist_px) {
|
if (dist_px) {
|
||||||
/* sample rect to increase chances of selecting, so that when clicking
|
/* sample rect to increase chances of selecting, so that when clicking
|
||||||
* on an edge in the backbuf, we can still select a face */
|
* on an edge in the backbuf, we can still select a face */
|
||||||
|
|
||||||
ED_view3d_select_id_validate(&vc);
|
|
||||||
|
|
||||||
*r_index = ED_view3d_select_id_read_nearest(&vc, mval, 1, me->totpoly + 1, &dist_px);
|
*r_index = ED_view3d_select_id_read_nearest(&vc, mval, 1, me->totpoly + 1, &dist_px);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1291,14 +1289,12 @@ bool ED_mesh_pick_vert(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ED_view3d_viewcontext_init(C, &vc);
|
ED_view3d_viewcontext_init(C, &vc);
|
||||||
|
ED_view3d_select_id_validate(&vc);
|
||||||
|
|
||||||
if (use_zbuf) {
|
if (use_zbuf) {
|
||||||
if (dist_px > 0) {
|
if (dist_px > 0) {
|
||||||
/* sample rect to increase chances of selecting, so that when clicking
|
/* sample rect to increase chances of selecting, so that when clicking
|
||||||
* on an face in the backbuf, we can still select a vert */
|
* on an face in the backbuf, we can still select a vert */
|
||||||
|
|
||||||
ED_view3d_select_id_validate(&vc);
|
|
||||||
|
|
||||||
*r_index = ED_view3d_select_id_read_nearest(&vc, mval, 1, me->totvert + 1, &dist_px);
|
*r_index = ED_view3d_select_id_read_nearest(&vc, mval, 1, me->totvert + 1, &dist_px);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -389,6 +389,7 @@ static int imapaint_pick_face(ViewContext *vc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* sample only on the exact position */
|
/* sample only on the exact position */
|
||||||
|
ED_view3d_select_id_validate(vc);
|
||||||
*r_index = ED_view3d_select_id_sample(vc, mval[0], mval[1]);
|
*r_index = ED_view3d_select_id_sample(vc, mval[0], mval[1]);
|
||||||
|
|
||||||
if ((*r_index) == 0 || (*r_index) > (unsigned int)totpoly) {
|
if ((*r_index) == 0 || (*r_index) > (unsigned int)totpoly) {
|
||||||
|
|||||||
@@ -41,7 +41,6 @@
|
|||||||
#include "GPU_batch.h"
|
#include "GPU_batch.h"
|
||||||
#include "GPU_matrix.h"
|
#include "GPU_matrix.h"
|
||||||
#include "GPU_state.h"
|
#include "GPU_state.h"
|
||||||
#include "GPU_framebuffer.h"
|
|
||||||
|
|
||||||
#include "ED_mesh.h"
|
#include "ED_mesh.h"
|
||||||
|
|
||||||
@@ -51,8 +50,6 @@
|
|||||||
|
|
||||||
#include "view3d_intern.h" /* bad level include */
|
#include "view3d_intern.h" /* bad level include */
|
||||||
|
|
||||||
#include "../../draw/intern/draw_cache_impl.h" /* bad level include (temporary) */
|
|
||||||
|
|
||||||
int view3d_effective_drawtype(const struct View3D *v3d)
|
int view3d_effective_drawtype(const struct View3D *v3d)
|
||||||
{
|
{
|
||||||
if (v3d->shading.type == OB_RENDER) {
|
if (v3d->shading.type == OB_RENDER) {
|
||||||
@@ -61,24 +58,6 @@ int view3d_effective_drawtype(const struct View3D *v3d)
|
|||||||
return v3d->shading.type;
|
return v3d->shading.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
|
|
||||||
{
|
|
||||||
if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (G.f & G_FLAG_BACKBUFSEL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if its drawing textures with zbuf sel, then don't draw dots */
|
|
||||||
if (dt == OB_TEXTURE && vd->shading.type == OB_TEXTURE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OpenGL Circle Drawing - Tables for Optimized Drawing Speed */
|
/* OpenGL Circle Drawing - Tables for Optimized Drawing Speed */
|
||||||
/* 32 values of sin function (still same result!) */
|
/* 32 values of sin function (still same result!) */
|
||||||
#define CIRCLE_RESOL 32
|
#define CIRCLE_RESOL 32
|
||||||
@@ -138,222 +117,6 @@ bool view3d_camera_border_hack_test = false;
|
|||||||
|
|
||||||
/* ***************** BACKBUF SEL (BBS) ********* */
|
/* ***************** BACKBUF SEL (BBS) ********* */
|
||||||
|
|
||||||
/** See #DRW_shgroup_world_clip_planes_from_rv3d, same function for draw manager. */
|
|
||||||
static void bbs_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4])
|
|
||||||
{
|
|
||||||
GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bbs_mesh_verts(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
|
|
||||||
{
|
|
||||||
GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
|
|
||||||
|
|
||||||
const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
|
|
||||||
GPU_SHADER_CFG_DEFAULT;
|
|
||||||
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
|
|
||||||
GPU_batch_uniform_1ui(batch, "offset", offset);
|
|
||||||
if (world_clip_planes != NULL) {
|
|
||||||
bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
|
||||||
}
|
|
||||||
GPU_batch_draw(batch);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bbs_mesh_wire(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
|
|
||||||
{
|
|
||||||
GPU_line_width(1.0f);
|
|
||||||
glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
|
|
||||||
|
|
||||||
const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
|
|
||||||
GPU_SHADER_CFG_DEFAULT;
|
|
||||||
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
|
|
||||||
GPU_batch_uniform_1ui(batch, "offset", offset);
|
|
||||||
if (world_clip_planes != NULL) {
|
|
||||||
bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
|
||||||
}
|
|
||||||
GPU_batch_draw(batch);
|
|
||||||
|
|
||||||
glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* two options, facecolors or black */
|
|
||||||
static void bbs_mesh_face(GPUBatch *batch,
|
|
||||||
const bool use_select,
|
|
||||||
const float world_clip_planes[6][4])
|
|
||||||
{
|
|
||||||
if (use_select) {
|
|
||||||
const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
|
|
||||||
GPU_SHADER_CFG_DEFAULT;
|
|
||||||
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
|
|
||||||
GPU_batch_uniform_1ui(batch, "offset", 1);
|
|
||||||
if (world_clip_planes != NULL) {
|
|
||||||
bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
|
||||||
}
|
|
||||||
GPU_batch_draw(batch);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
|
|
||||||
GPU_SHADER_CFG_DEFAULT;
|
|
||||||
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID, sh_cfg);
|
|
||||||
GPU_batch_uniform_1ui(batch, "id", 0);
|
|
||||||
if (world_clip_planes != NULL) {
|
|
||||||
bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
|
||||||
}
|
|
||||||
GPU_batch_draw(batch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bbs_mesh_face_dot(GPUBatch *batch, const float world_clip_planes[6][4])
|
|
||||||
{
|
|
||||||
const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
|
|
||||||
GPU_SHADER_CFG_DEFAULT;
|
|
||||||
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg);
|
|
||||||
GPU_batch_uniform_1ui(batch, "offset", 1);
|
|
||||||
if (world_clip_planes != NULL) {
|
|
||||||
bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
|
||||||
}
|
|
||||||
GPU_batch_draw(batch);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph),
|
|
||||||
Scene *UNUSED(scene),
|
|
||||||
Object *ob,
|
|
||||||
const float world_clip_planes[6][4])
|
|
||||||
{
|
|
||||||
Mesh *me = ob->data;
|
|
||||||
|
|
||||||
DRW_mesh_batch_cache_validate(me);
|
|
||||||
|
|
||||||
GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
|
|
||||||
GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
|
|
||||||
DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
|
|
||||||
|
|
||||||
/* Only draw faces to mask out verts, we don't want their selection ID's. */
|
|
||||||
bbs_mesh_face(geom_faces, false, world_clip_planes);
|
|
||||||
bbs_mesh_verts(geom_verts, 1, world_clip_planes);
|
|
||||||
|
|
||||||
bm_vertoffs = me->totvert + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bbs_mesh_solid_faces(Scene *UNUSED(scene),
|
|
||||||
Object *ob,
|
|
||||||
const float world_clip_planes[6][4])
|
|
||||||
{
|
|
||||||
Mesh *me = ob->data;
|
|
||||||
Mesh *me_orig = DEG_get_original_object(ob)->data;
|
|
||||||
|
|
||||||
DRW_mesh_batch_cache_validate(me);
|
|
||||||
|
|
||||||
const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL);
|
|
||||||
GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
|
|
||||||
DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, use_hide);
|
|
||||||
|
|
||||||
bbs_mesh_face(geom_faces, true, world_clip_planes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_object_select_id(Depsgraph *depsgraph,
|
|
||||||
Scene *scene,
|
|
||||||
View3D *v3d,
|
|
||||||
RegionView3D *rv3d,
|
|
||||||
Object *ob,
|
|
||||||
short select_mode)
|
|
||||||
{
|
|
||||||
ToolSettings *ts = scene->toolsettings;
|
|
||||||
if (select_mode == -1) {
|
|
||||||
select_mode = ts->selectmode;
|
|
||||||
}
|
|
||||||
|
|
||||||
GPU_matrix_mul(ob->obmat);
|
|
||||||
GPU_depth_test(true);
|
|
||||||
|
|
||||||
const float(*world_clip_planes)[4] = NULL;
|
|
||||||
if (rv3d->rflag & RV3D_CLIPPING) {
|
|
||||||
ED_view3d_clipping_local(rv3d, ob->obmat);
|
|
||||||
world_clip_planes = rv3d->clip_local;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ob->type) {
|
|
||||||
case OB_MESH:
|
|
||||||
if (ob->mode & OB_MODE_EDIT) {
|
|
||||||
Mesh *me = ob->data;
|
|
||||||
BMEditMesh *em = me->edit_mesh;
|
|
||||||
const bool draw_facedot = check_ob_drawface_dot(scene, v3d, ob->dt);
|
|
||||||
const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0;
|
|
||||||
|
|
||||||
DRW_mesh_batch_cache_validate(me);
|
|
||||||
|
|
||||||
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
|
|
||||||
|
|
||||||
GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots;
|
|
||||||
geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
|
|
||||||
if (select_mode & SCE_SELECT_EDGE) {
|
|
||||||
geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me);
|
|
||||||
}
|
|
||||||
if (select_mode & SCE_SELECT_VERTEX) {
|
|
||||||
geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
|
|
||||||
}
|
|
||||||
if (draw_facedot) {
|
|
||||||
geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me);
|
|
||||||
}
|
|
||||||
DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
|
|
||||||
|
|
||||||
bbs_mesh_face(geom_faces, use_faceselect, world_clip_planes);
|
|
||||||
|
|
||||||
if (use_faceselect && draw_facedot) {
|
|
||||||
bbs_mesh_face_dot(geom_facedots, world_clip_planes);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (select_mode & SCE_SELECT_FACE) {
|
|
||||||
bm_solidoffs = 1 + em->bm->totface;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bm_solidoffs = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ED_view3d_polygon_offset(rv3d, 1.0);
|
|
||||||
|
|
||||||
/* we draw edges if edge select mode */
|
|
||||||
if (select_mode & SCE_SELECT_EDGE) {
|
|
||||||
bbs_mesh_wire(geom_edges, bm_solidoffs, world_clip_planes);
|
|
||||||
bm_wireoffs = bm_solidoffs + em->bm->totedge;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* `bm_vertoffs` is calculated from `bm_wireoffs`. (otherwise see T53512) */
|
|
||||||
bm_wireoffs = bm_solidoffs;
|
|
||||||
}
|
|
||||||
|
|
||||||
ED_view3d_polygon_offset(rv3d, 1.1);
|
|
||||||
|
|
||||||
/* we draw verts if vert select mode. */
|
|
||||||
if (select_mode & SCE_SELECT_VERTEX) {
|
|
||||||
bbs_mesh_verts(geom_verts, bm_wireoffs, world_clip_planes);
|
|
||||||
bm_vertoffs = bm_wireoffs + em->bm->totvert;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bm_vertoffs = bm_wireoffs;
|
|
||||||
}
|
|
||||||
|
|
||||||
ED_view3d_polygon_offset(rv3d, 0.0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Mesh *me = DEG_get_original_object(ob)->data;
|
|
||||||
if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
|
|
||||||
/* currently vertex select supports weight paint and vertex paint*/
|
|
||||||
((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) {
|
|
||||||
bbs_mesh_solid_verts(depsgraph, scene, ob, world_clip_planes);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bbs_mesh_solid_faces(scene, ob, world_clip_planes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OB_CURVE:
|
|
||||||
case OB_SURF:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
GPU_matrix_set(rv3d->viewmat);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ED_draw_object_facemap(Depsgraph *depsgraph,
|
void ED_draw_object_facemap(Depsgraph *depsgraph,
|
||||||
Object *ob,
|
Object *ob,
|
||||||
const float col[4],
|
const float col[4],
|
||||||
|
|||||||
@@ -77,6 +77,7 @@
|
|||||||
#include "ED_armature.h"
|
#include "ED_armature.h"
|
||||||
#include "ED_keyframing.h"
|
#include "ED_keyframing.h"
|
||||||
#include "ED_gpencil.h"
|
#include "ED_gpencil.h"
|
||||||
|
#include "ED_mesh.h"
|
||||||
#include "ED_screen.h"
|
#include "ED_screen.h"
|
||||||
#include "ED_space_api.h"
|
#include "ED_space_api.h"
|
||||||
#include "ED_screen_types.h"
|
#include "ED_screen_types.h"
|
||||||
@@ -208,7 +209,16 @@ static void validate_object_select_id(struct Depsgraph *depsgraph,
|
|||||||
|
|
||||||
if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
|
if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
|
||||||
DRW_framebuffer_select_id_setup(ar, true);
|
DRW_framebuffer_select_id_setup(ar, true);
|
||||||
draw_object_select_id(depsgraph, scene_eval, v3d, rv3d, obact_eval, select_mode);
|
DRW_draw_select_id_object(scene_eval,
|
||||||
|
rv3d,
|
||||||
|
obact_eval,
|
||||||
|
select_mode,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
&bm_vertoffs,
|
||||||
|
&bm_wireoffs,
|
||||||
|
&bm_solidoffs);
|
||||||
|
|
||||||
DRW_framebuffer_select_id_release(ar);
|
DRW_framebuffer_select_id_release(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,10 +281,8 @@ void ED_view3d_backbuf_depth_validate(ViewContext *vc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint *ED_view3d_select_id_read_rect(ViewContext *vc, const rcti *clip, uint *r_buf_len)
|
uint *ED_view3d_select_id_read_rect(ViewContext *UNUSED(vc), const rcti *clip, uint *r_buf_len)
|
||||||
{
|
{
|
||||||
ED_view3d_select_id_validate(vc);
|
|
||||||
|
|
||||||
uint width = BLI_rcti_size_x(clip);
|
uint width = BLI_rcti_size_x(clip);
|
||||||
uint height = BLI_rcti_size_y(clip);
|
uint height = BLI_rcti_size_y(clip);
|
||||||
uint buf_len = width * height;
|
uint buf_len = width * height;
|
||||||
|
|||||||
@@ -304,16 +304,15 @@ static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const
|
|||||||
em_setup_viewcontext(C, &vc);
|
em_setup_viewcontext(C, &vc);
|
||||||
copy_v2_v2_int(vc.mval, mval);
|
copy_v2_v2_int(vc.mval, mval);
|
||||||
|
|
||||||
for (uint base_index = 0; base_index < gz_ring->bases_len; base_index++) {
|
uint base_index;
|
||||||
Object *ob_iter = gz_ring->bases[base_index]->object;
|
BMEdge *eed_test = EDBM_edge_find_nearest_ex(
|
||||||
ED_view3d_viewcontext_init_object(&vc, ob_iter);
|
&vc, &best.dist, NULL, false, false, NULL, gz_ring->bases, gz_ring->bases_len, &base_index);
|
||||||
BMEdge *eed_test = EDBM_edge_find_nearest_ex(&vc, &best.dist, NULL, false, false, NULL);
|
|
||||||
if (eed_test) {
|
if (eed_test) {
|
||||||
best.ob = ob_iter;
|
best.ob = gz_ring->bases[base_index]->object;
|
||||||
best.eed = eed_test;
|
best.eed = eed_test;
|
||||||
best.base_index = base_index;
|
best.base_index = base_index;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
BMesh *bm = NULL;
|
BMesh *bm = NULL;
|
||||||
if (best.eed) {
|
if (best.eed) {
|
||||||
|
|||||||
@@ -127,13 +127,6 @@ void VIEW3D_OT_fly(struct wmOperatorType *ot);
|
|||||||
void VIEW3D_OT_walk(struct wmOperatorType *ot);
|
void VIEW3D_OT_walk(struct wmOperatorType *ot);
|
||||||
|
|
||||||
/* drawobject.c */
|
/* drawobject.c */
|
||||||
void draw_object_select_id(struct Depsgraph *depsgraph,
|
|
||||||
Scene *scene,
|
|
||||||
View3D *v3d,
|
|
||||||
RegionView3D *rv3d,
|
|
||||||
struct Object *ob,
|
|
||||||
short select_mode);
|
|
||||||
|
|
||||||
int view3d_effective_drawtype(const struct View3D *v3d);
|
int view3d_effective_drawtype(const struct View3D *v3d);
|
||||||
|
|
||||||
/* view3d_draw.c */
|
/* view3d_draw.c */
|
||||||
|
|||||||
@@ -135,9 +135,6 @@ void ED_view3d_viewcontext_init_object(ViewContext *vc, Object *obact)
|
|||||||
if (vc->obedit) {
|
if (vc->obedit) {
|
||||||
BLI_assert(BKE_object_is_in_editmode(obact));
|
BLI_assert(BKE_object_is_in_editmode(obact));
|
||||||
vc->obedit = obact;
|
vc->obedit = obact;
|
||||||
/* previous selections are now invalid. */
|
|
||||||
vc->v3d->flag |= V3D_INVALID_BACKBUF;
|
|
||||||
|
|
||||||
if (vc->em) {
|
if (vc->em) {
|
||||||
vc->em = BKE_editmesh_from_object(vc->obedit);
|
vc->em = BKE_editmesh_from_object(vc->obedit);
|
||||||
}
|
}
|
||||||
@@ -2359,14 +2356,14 @@ static bool do_paintvert_box_select(ViewContext *vc, const rcti *rect, const eSe
|
|||||||
}
|
}
|
||||||
else if (use_zbuf) {
|
else if (use_zbuf) {
|
||||||
MVert *mvert;
|
MVert *mvert;
|
||||||
unsigned int *rt;
|
uint *rt, *buf, buf_len;
|
||||||
int a, index;
|
int a, index;
|
||||||
char *selar;
|
char *selar;
|
||||||
|
|
||||||
selar = MEM_callocN(me->totvert + 1, "selar");
|
selar = MEM_callocN(me->totvert + 1, "selar");
|
||||||
|
|
||||||
uint buf_len;
|
ED_view3d_select_id_validate(vc);
|
||||||
uint *buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
|
buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
|
||||||
|
|
||||||
rt = buf;
|
rt = buf;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user