[Bf-blender-cvs] [d3f8940] soc-2016-uv_tools: Select overlapping UVs operator
Phil Gosch
noreply at git.blender.org
Mon Jul 4 14:56:29 CEST 2016
Commit: d3f89408c7c47b3ddd264ed1b4161da7fb6e2d3c
Author: Phil Gosch
Date: Mon Jul 4 14:54:52 2016 +0200
Branches: soc-2016-uv_tools
https://developer.blender.org/rBd3f89408c7c47b3ddd264ed1b4161da7fb6e2d3c
Select overlapping UVs operator
Found via Select->Select all by trait->Overlapping UVs menu entry, selects all UV charts which overlap/intersect
Operator has an "Extend" option to extend the current selection.
I also turned rectangle/bounds intersection test into a seperate function which can be reused
===================================================================
M release/scripts/startup/bl_ui/space_image.py
M source/blender/editors/include/ED_uvedit.h
M source/blender/editors/uvedit/uvedit_ops.c
M source/blender/editors/uvedit/uvedit_parametrizer.c
M source/blender/editors/uvedit/uvedit_parametrizer.h
M source/blender/editors/uvedit/uvedit_unwrap_ops.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 4811bd4..0d60b02 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -126,6 +126,12 @@ class IMAGE_MT_view(Menu):
layout.operator("screen.screen_full_area")
layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True
+class IMAGE_MT_uvs_select_by_trait(Menu):
+ bl_label = "Select All by Trait"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator("uv.select_overlapping")
class IMAGE_MT_select(Menu):
bl_label = "Select"
@@ -149,6 +155,8 @@ class IMAGE_MT_select(Menu):
layout.operator("uv.select_shortest_path")
layout.separator()
+ layout.menu("IMAGE_MT_uvs_select_by_trait")
+ layout.separator()
layout.operator("uv.select_less", text="Less")
layout.operator("uv.select_more", text="More")
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index c5a1e66..4e5ef0d 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -108,6 +108,9 @@ void ED_uvedit_unwrap_cube_project(struct Object *ob, struct BMesh *bm, float cu
/* single call up unwrap using scene settings, used for edge tag unwrapping */
void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel);
+/* select by trait */
+void ED_uvedit_overlapping_select(struct Scene *scene, struct OBject *ob, struct BMesh *bm, const bool extend);
+
/* select shortest path */
bool ED_uvedit_shortest_path_select(struct Scene *scene, struct Object *ob, struct BMesh *bm, bool topo_dist);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 20bcfc5..b499f70 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -4288,6 +4288,38 @@ static void UV_OT_select_mesh(wmOperatorType *ot)
ot->poll = ED_operator_uvedit;
}
+/******************** select overlapping operator ********************/
+
+static int UV_OT_select_overlapping_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
+
+ ED_uvedit_overlapping_select(scene, obedit, bm, extend);
+
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+static void UV_OT_select_overlapping(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Overlapping UVs";
+ ot->description = "Select all overlapping UV islands";
+ ot->idname = "UV_OT_select_overlapping";
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec = UV_OT_select_overlapping_exec;
+ ot->poll = ED_operator_uvedit;
+
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend current selection");
+}
+
/******************** set 3d cursor operator ********************/
static int uv_set_2d_cursor_poll(bContext *C)
@@ -4645,6 +4677,7 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_select_more);
WM_operatortype_append(UV_OT_select_less);
WM_operatortype_append(UV_OT_select_shortest_path);
+ WM_operatortype_append(UV_OT_select_overlapping);
WM_operatortype_append(UV_OT_snap_cursor);
WM_operatortype_append(UV_OT_snap_selected);
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 5ac81d2..7835bb6 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -621,6 +621,18 @@ static PBool p_intersect_line_segments_2d(float *a, float *b, float *c, float *d
return P_FALSE;
}
+bool p_rect_intersect(float min1[2], float max1[2], float min2[2], float max2[2])
+{
+ if (min1[0] > max2[0] ||
+ max1[0] < min2[0] ||
+ min1[1] > max2[1] ||
+ max1[1] < min2[1]) {
+ return false;
+ }
+
+ return true;
+}
+
/* Topological Utilities */
static PEdge *p_wheel_edge_next(PEdge *e)
@@ -761,6 +773,12 @@ static void p_flush_uvs(PHandle *handle, PChart *chart)
sel_flag |= MLOOPVERT_SELECTED; /* MLOOPUV_VERTSEL*/
*(e->orig_flag) = sel_flag;
}
+ else {
+ sel_flag = *e->orig_flag;
+ sel_flag &= ~MLOOPEDGE_SELECTED;/* MLOOPUV_EDGESEL*/
+ sel_flag &= ~MLOOPVERT_SELECTED; /* MLOOPUV_VERTSEL*/
+ *(e->orig_flag) = sel_flag;
+ }
}
}
@@ -1468,6 +1486,46 @@ static void p_chart_fill_boundaries(PChart *chart, PEdge *outer)
}
}
+static bool p_charts_intersect(PChart* a, PChart *b)
+{
+ PEdge *e1, *e2;
+ float min1[2], min2[2], max1[2], max2[2];
+
+ /* Check for overlapping bounding rectangles */
+ p_chart_uv_bbox(a, min1, max1);
+ p_chart_uv_bbox(b, min2, max2);
+
+ if (!p_rect_intersect(min1, max1, min2, max2)) {
+ return false;
+ }
+
+ /* Check edges for intersections */
+ for (e1 = a->edges; e1; e1 = e1->nextlink) {
+ for (e2 = b->edges; e2; e2 = e2->nextlink) {
+ if (p_intersect_line_segaments_2d(e1->vert->uv,
+ e1->nextlink->vert->uv,
+ e2->vert->uv,
+ e2->nextlink->vert->uv)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static void p_chart_select(PChart *chart, bool select)
+{
+ PEdge *e;
+
+ for (e = chart->edges; e; e = e->nextlink) {
+ if (select)
+ e->flag |= PEDGE_SELECT;
+ else
+ e->flag &= ~PEDGE_SELECT;
+ }
+}
+
#if 0
/* Polygon kernel for inserting uv's non overlapping */
@@ -4730,10 +4788,7 @@ void p_convex_hull_delete(PConvexHull *c_hull)
bool p_convex_hull_intersect(PConvexHull *chull_a, PConvexHull *chull_b)
{
/* Preliminary bounds check */
- if (chull_a->min_v[0] > chull_b->max_v[0] ||
- chull_a->max_v[0] < chull_b->min_v[0] ||
- chull_a->min_v[1] > chull_b->max_v[1] ||
- chull_a->max_v[1] < chull_b->min_v[1]) {
+ if (!p_rect_intersect(chull_a->min_v, chull_a->max_v, chull_b->min_v, chull_b->max_v)) {
return false;
}
@@ -5336,6 +5391,36 @@ void param_shortest_path(ParamHandle *handle, bool *p_found, bool topological_di
*p_found = success;
}
+void param_select_overlapping(ParamHandle *handle, const bool extend)
+{
+ PHandle *phandle = (PHandle *)handle;
+ PChart *chart1, *chart2;
+ int i, j;
+
+ /* deselect charts */
+ if (!extend)
+ {
+ for (i = 0; i < phandle->ncharts; i++) {
+ chart1 = phandle->charts[i];
+ p_chart_select(chart1, false);
+ }
+ }
+
+ /* Check charts for intersections/overlaps */
+ for (i = 0; i < phandle->ncharts; i++) {
+ chart1 = phandle->charts[i];
+
+ for (j = 0; j < phandle->ncharts; j++) {
+ chart2 = phandle->charts[j];
+ if ((i != j) && p_charts_intersect(chart1, chart2)) {
+ /* select charts */
+ p_chart_select(chart1, true);
+ p_chart_select(chart2, true);
+ }
+ }
+ }
+}
+
void param_flush(ParamHandle *handle)
{
PHandle *phandle = (PHandle *)handle;
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.h b/source/blender/editors/uvedit/uvedit_parametrizer.h
index 5e48ff4..1460b22 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.h
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.h
@@ -124,6 +124,10 @@ void param_scale_bounds(ParamHandle *handle);
void param_shortest_path(ParamHandle *handle, bool *p_found, bool topological_distance);
+/* Select Overlapping */
+
+void param_select_overlapping(ParamHandle *handle, bool extend);
+
/* Flushing */
void param_flush(ParamHandle *handle);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 7b03258..9f9cf7a 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -750,6 +750,17 @@ bool ED_uvedit_shortest_path_select(Scene *scene, Object *ob, BMesh *bm, bool to
return path_found;
}
+/* ******************** Select Overlapping UVs operator **************** */
+void ED_uvedit_overlapping_select(Scene *scene, Object *ob, BMesh *bm, const bool extend)
+{
+ ParamHandle *handle;
+ int hparams = set_handle_params(true, false, false, true, true);
+ handle = construct_param_handle(scene, ob, bm, hparams);
+ param_select_overlapping(handle, extend);
+ param_flush(handle);
+ param_delete(handle);
+}
+
/* ******************** Scale To Bounds operator **************** */
void ED_uvedit_scale_to_bounds(Scene *scene, Object *ob, BMesh *bm)
{
More information about the Bf-blender-cvs
mailing list