Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2018-09-09 09:11:02 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-09-10 07:35:04 +0300
commit20634fd433b07bbd90358a625792292e9581a0f6 (patch)
treeb6be45ddf341ce7d2dc8c85a67480e6815d4a6e6 /source/blender/editors/space_view3d
parent2b5d4d426a9b8483539d14b6e9ab90da262c2ecb (diff)
Tool System: use preselect highlight w/ poly-build
- Poly build now uses a new gizmo for pre-selection which has the same behavior as loop-cut. This replaces hack where mouse-move set the active element which was no longer working properly because of missing depsgraph updates. - Multi-object support for poly-build. - Support for deformed cage. - Fix error where changing active object wasn't properly refreshing the preselect gizmo (for loopcut too). Currently holding Alt to select non-boundary element's isn't working.
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect.c48
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c220
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h1
4 files changed, 267 insertions, 3 deletions
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index a8e530540a1..c1c097b6e3d 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -702,6 +702,7 @@ static void view3d_widgets(void)
WM_gizmogrouptype_append(TRANSFORM_GGT_gizmo);
WM_gizmogrouptype_append(VIEW3D_GGT_xform_cage);
+ WM_gizmogrouptype_append(VIEW3D_GGT_mesh_preselect_elem);
WM_gizmogrouptype_append(VIEW3D_GGT_mesh_preselect_edgering);
WM_gizmogrouptype_append(VIEW3D_GGT_ruler);
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
index aebad326a57..e7a35c39bf3 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
@@ -41,6 +41,54 @@
#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
+/** \name Mesh Pre-Select Element Gizmo
+ *
+ * \{ */
+
+struct GizmoGroupPreSelElem {
+ wmGizmo *gizmo;
+};
+
+static bool WIDGETGROUP_mesh_preselect_elem_poll(const bContext *C, wmGizmoGroupType *gzgt)
+{
+ bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C);
+ if ((tref_rt == NULL) ||
+ !STREQ(gzgt->idname, tref_rt->gizmo_group))
+ {
+ WM_gizmo_group_type_unlink_delayed_ptr(gzgt);
+ return false;
+ }
+ return true;
+}
+
+static void WIDGETGROUP_mesh_preselect_elem_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+{
+ const wmGizmoType *gzt_presel = WM_gizmotype_find("GIZMO_GT_preselect_elem_3d", true);
+ struct GizmoGroupPreSelElem *man = MEM_callocN(sizeof(struct GizmoGroupPreSelElem), __func__);
+ gzgroup->customdata = man;
+
+ wmGizmo *gz = man->gizmo = WM_gizmo_new_ptr(gzt_presel, gzgroup, NULL);
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+}
+
+void VIEW3D_GGT_mesh_preselect_elem(wmGizmoGroupType *gzgt)
+{
+ gzgt->name = "Mesh Preselect Element";
+ gzgt->idname = "VIEW3D_GGT_mesh_preselect_elem";
+
+ gzgt->flag = WM_GIZMOGROUPTYPE_3D;
+
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
+
+ gzgt->poll = WIDGETGROUP_mesh_preselect_elem_poll;
+ gzgt->setup = WIDGETGROUP_mesh_preselect_elem_setup;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Mesh Pre-Select Edge Ring Gizmo
*
* \{ */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
index fffca6c0887..33de6621db3 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
@@ -55,6 +55,207 @@
#include "ED_gizmo_library.h"
/* -------------------------------------------------------------------- */
+/** \name Mesh Element (Vert/Edge/Face) Pre-Select Gizmo API
+ *
+ * \{ */
+
+
+typedef struct MeshElemGizmo3D {
+ wmGizmo gizmo;
+ Object **objects;
+ uint objects_len;
+ int object_index;
+ int vert_index;
+ int edge_index;
+ int face_index;
+ struct EditMesh_PreSelElem *psel;
+} MeshElemGizmo3D;
+
+static void gizmo_preselect_elem_draw(const bContext *UNUSED(C), wmGizmo *gz)
+{
+ MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
+ if (gz_ele->object_index != -1) {
+ Object *ob = gz_ele->objects[gz_ele->object_index];
+ EDBM_preselect_elem_draw(gz_ele->psel, ob->obmat);
+ }
+}
+
+static int gizmo_preselect_elem_test_select(
+ bContext *C, wmGizmo *gz, const int mval[2])
+{
+ MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
+ struct {
+ Object *ob;
+ BMElem *ele;
+ float dist;
+ int ob_index;
+ } best = {
+ .dist = ED_view3d_select_dist_px(),
+ };
+
+ struct {
+ int object_index;
+ int vert_index;
+ int edge_index;
+ int face_index;
+ } prev = {
+ .object_index = gz_ele->object_index,
+ .vert_index = gz_ele->vert_index,
+ .edge_index = gz_ele->edge_index,
+ .face_index = gz_ele->face_index,
+ };
+
+ {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ if (((gz_ele->objects)) == NULL ||
+ (gz_ele->objects[0] != OBEDIT_FROM_VIEW_LAYER(view_layer)))
+ {
+ gz_ele->objects = BKE_view_layer_array_from_objects_in_edit_mode(
+ view_layer, &gz_ele->objects_len);
+ }
+ }
+
+ ViewContext vc;
+ em_setup_viewcontext(C, &vc);
+ copy_v2_v2_int(vc.mval, mval);
+
+ {
+ /* TODO: support faces. */
+ Base *base = NULL;
+ BMVert *eve_test;
+ BMEdge *eed_test;
+
+ if (EDBM_unified_findnearest_from_raycast(&vc, true, &base, &eve_test, &eed_test, NULL)) {
+ best.ob = base->object;
+ if (eve_test) {
+ best.ele = (BMElem *)eve_test;
+ }
+ else if (eed_test) {
+ best.ele = (BMElem *)eed_test;
+ }
+ else {
+ BLI_assert(0);
+ }
+ best.ob_index = -1;
+ /* weak, we could ensure the arrays are aligned,
+ * or allow EDBM_unified_findnearest_from_raycast to take an array arg. */
+ for (int ob_index = 0; ob_index < gz_ele->objects_len; ob_index++) {
+ if (best.ob == gz_ele->objects[ob_index]) {
+ best.ob_index = ob_index;
+ break;
+ }
+ }
+ /* Check above should never fail, if it does it's an internal error. */
+ BLI_assert(best.ob_index != -1);
+ }
+ }
+
+ BMesh *bm = NULL;
+
+ gz_ele->object_index = -1;
+ gz_ele->vert_index = -1;
+ gz_ele->edge_index = -1;
+ gz_ele->face_index = -1;
+
+ if (best.ele) {
+ gz_ele->object_index = best.ob_index;
+ bm = BKE_editmesh_from_object(gz_ele->objects[gz_ele->object_index])->bm;
+ BM_mesh_elem_index_ensure(bm, best.ele->head.htype);
+
+ if (best.ele->head.htype == BM_VERT) {
+ gz_ele->vert_index = BM_elem_index_get(best.ele);
+ }
+ else if (best.ele->head.htype == BM_EDGE) {
+ gz_ele->edge_index = BM_elem_index_get(best.ele);
+ }
+ else if (best.ele->head.htype == BM_FACE) {
+ gz_ele->face_index = BM_elem_index_get(best.ele);
+ }
+ }
+
+ if ((prev.object_index == gz_ele->object_index) &&
+ (prev.vert_index == gz_ele->vert_index) &&
+ (prev.edge_index == gz_ele->edge_index) &&
+ (prev.face_index == gz_ele->face_index))
+ {
+ /* pass (only recalculate on change) */
+ }
+ else {
+ if (best.ele) {
+ const float (*coords)[3] = NULL;
+ {
+ Object *ob = gz_ele->objects[gz_ele->object_index];
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
+ if (me_eval->runtime.edit_data) {
+ coords = me_eval->runtime.edit_data->vertexCos;
+ }
+ }
+ EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords);
+ }
+ else {
+ EDBM_preselect_elem_clear(gz_ele->psel);
+ }
+
+ RNA_int_set(gz->ptr, "object_index", gz_ele->object_index);
+ RNA_int_set(gz->ptr, "vert_index", gz_ele->vert_index);
+ RNA_int_set(gz->ptr, "edge_index", gz_ele->edge_index);
+ RNA_int_set(gz->ptr, "face_index", gz_ele->face_index);
+
+ ARegion *ar = CTX_wm_region(C);
+ ED_region_tag_redraw(ar);
+ }
+
+ // return best.eed ? 0 : -1;
+ return -1;
+}
+
+static void gizmo_preselect_elem_setup(wmGizmo *gz)
+{
+ MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
+ if (gz_ele->psel == NULL) {
+ gz_ele->psel = EDBM_preselect_elem_create();
+ }
+ gz_ele->object_index = -1;
+}
+
+static void gizmo_preselect_elem_free(wmGizmo *gz)
+{
+ MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
+ EDBM_preselect_elem_destroy(gz_ele->psel);
+ gz_ele->psel = NULL;
+ MEM_SAFE_FREE(gz_ele->objects);
+}
+
+static int gizmo_preselect_elem_invoke(
+ bContext *UNUSED(C), wmGizmo *UNUSED(gz), const wmEvent *UNUSED(event))
+{
+ return OPERATOR_PASS_THROUGH;
+}
+
+static void GIZMO_GT_preselect_elem_3d(wmGizmoType *gzt)
+{
+ /* identifiers */
+ gzt->idname = "GIZMO_GT_preselect_elem_3d";
+
+ /* api callbacks */
+ gzt->invoke = gizmo_preselect_elem_invoke;
+ gzt->draw = gizmo_preselect_elem_draw;
+ gzt->test_select = gizmo_preselect_elem_test_select;
+ gzt->setup = gizmo_preselect_elem_setup;
+ gzt->free = gizmo_preselect_elem_free;
+
+ gzt->struct_size = sizeof(MeshElemGizmo3D);
+
+ RNA_def_int(gzt->srna, "object_index", -1, -1, INT_MAX, "Object Index", "", -1, INT_MAX);
+ RNA_def_int(gzt->srna, "vert_index", -1, -1, INT_MAX, "Vert Index", "", -1, INT_MAX);
+ RNA_def_int(gzt->srna, "edge_index", -1, -1, INT_MAX, "Edge Index", "", -1, INT_MAX);
+ RNA_def_int(gzt->srna, "face_index", -1, -1, INT_MAX, "Face Index", "", -1, INT_MAX);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Mesh Edge-Ring Pre-Select Gizmo API
*
* \{ */
@@ -98,10 +299,14 @@ static int gizmo_preselect_edgering_test_select(
.edge_index = gz_ring->edge_index,
};
- if (gz_ring->objects == NULL) {
+ {
ViewLayer *view_layer = CTX_data_view_layer(C);
- gz_ring->objects = BKE_view_layer_array_from_objects_in_edit_mode(
- view_layer, &gz_ring->objects_len);
+ if (((gz_ring->objects)) == NULL ||
+ (gz_ring->objects[0] != OBEDIT_FROM_VIEW_LAYER(view_layer)))
+ {
+ gz_ring->objects = BKE_view_layer_array_from_objects_in_edit_mode(
+ view_layer, &gz_ring->objects_len);
+ }
}
ViewContext vc;
@@ -207,8 +412,17 @@ static void GIZMO_GT_preselect_edgering_3d(wmGizmoType *gzt)
RNA_def_int(gzt->srna, "edge_index", -1, -1, INT_MAX, "Edge Index", "", -1, INT_MAX);
}
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+/** \name Gizmo API
+ *
+ * \{ */
+
void ED_gizmotypes_preselect_3d(void)
{
+ WM_gizmotype_append(GIZMO_GT_preselect_elem_3d);
WM_gizmotype_append(GIZMO_GT_preselect_edgering_3d);
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index e4ef442d49a..b8edbfe9b65 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -263,6 +263,7 @@ void VIEW3D_GGT_force_field(struct wmGizmoGroupType *gzgt);
void VIEW3D_GGT_empty_image(struct wmGizmoGroupType *gzgt);
void VIEW3D_GGT_armature_spline(struct wmGizmoGroupType *gzgt);
void VIEW3D_GGT_navigate(struct wmGizmoGroupType *gzgt);
+void VIEW3D_GGT_mesh_preselect_elem(struct wmGizmoGroupType *gzgt);
void VIEW3D_GGT_mesh_preselect_edgering(struct wmGizmoGroupType *gzgt);
void VIEW3D_GGT_ruler(struct wmGizmoGroupType *gzgt);