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:
authorAlan <Al@AlanTroth.me.uk>2018-09-07 12:45:34 +0300
committerDalai Felinto <dfelinto@gmail.com>2018-09-07 13:08:12 +0300
commit601fd9683cf59a789f0bbf2157724f3051428da2 (patch)
treeb76d72631bcb4fdc0ad504925c9a5f5897e10c3b /source/blender/editors/uvedit/uvedit_smart_stitch.c
parentdb259e0889e769eca825ba9865fcd20e020df4c6 (diff)
Multi-Objects: UV_OT_stitch
Reviewers: dfelinto https://developer.blender.org/D3645
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_smart_stitch.c')
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c184
1 files changed, 141 insertions, 43 deletions
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 420cfb199f2..b33d76a222c 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -233,6 +233,18 @@ enum StitchModes {
STITCH_EDGE
};
+/* UvElement identification. */
+typedef struct UvElementID {
+ int faceIndex;
+ int elementIndex;
+} UvElementID;
+
+/* StitchState initializition. */
+typedef struct StitchStateInit {
+ int uv_selected_count;
+ UvElementID *to_select;
+} StitchStateInit;
+
/* constructor */
static StitchPreviewer *stitch_preview_init(void)
{
@@ -1812,7 +1824,7 @@ static UvEdge *uv_edge_get(BMLoop *l, StitchState *state)
static StitchState *stitch_init(
bContext *C, wmOperator *op,
- StitchStateContainer *ssc, Object *obedit)
+ StitchStateContainer *ssc, Object *obedit, StitchStateInit *state_init)
{
/* for fast edge lookup... */
GHash *edge_hash;
@@ -1997,36 +2009,34 @@ static StitchState *stitch_init(
state->selection_size = 0;
/* Load old selection if redoing operator with different settings */
- /* WIP */
- if (false && RNA_struct_property_is_set(op->ptr, "selection")) {
+ if (state_init != NULL) {
int faceIndex, elementIndex;
UvElement *element;
enum StitchModes stored_mode = RNA_enum_get(op->ptr, "stored_mode");
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
+ int selected_count = state_init->uv_selected_count;
+
if (stored_mode == STITCH_VERT) {
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack");
- RNA_BEGIN (op->ptr, itemptr, "selection")
- {
- faceIndex = RNA_int_get(&itemptr, "face_index");
- elementIndex = RNA_int_get(&itemptr, "element_index");
+ while (selected_count--) {
+ faceIndex = state_init->to_select[selected_count].faceIndex;
+ elementIndex = state_init->to_select[selected_count].elementIndex;
efa = BM_face_at_index(em->bm, faceIndex);
element = BM_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
stitch_select_uv(element, state, 1);
}
- RNA_END;
}
else {
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack");
- RNA_BEGIN (op->ptr, itemptr, "selection")
- {
+ while (selected_count--) {
UvEdge tmp_edge, *edge;
int uv1, uv2;
- faceIndex = RNA_int_get(&itemptr, "face_index");
- elementIndex = RNA_int_get(&itemptr, "element_index");
+ faceIndex = state_init->to_select[selected_count].faceIndex;
+ elementIndex = state_init->to_select[selected_count].elementIndex;
efa = BM_face_at_index(em->bm, faceIndex);
element = BM_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
uv1 = map[element - state->element_map->buf];
@@ -2047,16 +2057,12 @@ static StitchState *stitch_init(
stitch_select_edge(edge, state, true);
}
- RNA_END;
}
/* if user has switched the operator mode after operation, we need to convert
* the stored format */
if (ssc->mode != stored_mode) {
stitch_set_selection_mode(state, stored_mode);
}
- /* Clear the selection */
- RNA_collection_clear(op->ptr, "selection");
-
}
else {
if (ssc->mode == STITCH_VERT) {
@@ -2211,10 +2217,54 @@ static int stitch_init_all(bContext *C, wmOperator *op)
ssc->states = MEM_callocN(sizeof(StitchState *) * objects_len, "StitchState");
ssc->objects_len = 0;
+ int *objs_selection_count = NULL;
+ UvElementID *selected_uvs_arr = NULL;
+ StitchStateInit *state_init = NULL;
+
+ if (RNA_struct_property_is_set(op->ptr, "selection") &&
+ RNA_struct_property_is_set(op->ptr, "objects_selection_count"))
+ {
+ /* Retrieve list of selected UVs, one list contains all selected UVs
+ * for all objects. */
+
+ objs_selection_count = MEM_mallocN(sizeof(int *) * objects_len, "objects_selection_count");
+ RNA_int_get_array(op->ptr, "objects_selection_count", objs_selection_count);
+
+ int total_selected = 0;
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ total_selected += objs_selection_count[ob_index];
+ }
+
+ selected_uvs_arr = MEM_callocN(sizeof(UvElementID) * total_selected, "selected_uvs_arr");
+ int sel_idx = 0;
+ RNA_BEGIN (op->ptr, itemptr, "selection")
+ {
+ BLI_assert(sel_idx < total_selected);
+ selected_uvs_arr[sel_idx].faceIndex = RNA_int_get(&itemptr, "face_index");
+ selected_uvs_arr[sel_idx].elementIndex = RNA_int_get(&itemptr, "element_index");
+ sel_idx++;
+ }
+ RNA_END;
+
+ RNA_collection_clear(op->ptr, "selection");
+
+ state_init = MEM_callocN(sizeof(StitchStateInit), "UV_init_selected");
+ state_init->to_select = selected_uvs_arr;
+ }
+
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
- StitchState *stitch_state_ob = stitch_init(C, op, ssc, obedit);
+ if (state_init != NULL) {
+ state_init->uv_selected_count = objs_selection_count[ob_index];
+ }
+
+ StitchState *stitch_state_ob = stitch_init(C, op, ssc, obedit, state_init);
+
+ if (state_init != NULL) {
+ /* Move pointer to beginning of next object's data. */
+ state_init->to_select += state_init->uv_selected_count;
+ }
if (stitch_state_ob) {
ssc->objects[ssc->objects_len] = obedit;
@@ -2224,6 +2274,9 @@ static int stitch_init_all(bContext *C, wmOperator *op)
}
MEM_freeN(objects);
+ MEM_SAFE_FREE(selected_uvs_arr);
+ MEM_SAFE_FREE(objs_selection_count);
+ MEM_SAFE_FREE(state_init);
if (ssc->objects_len == 0) {
state_delete_all(ssc);
@@ -2257,31 +2310,41 @@ static int stitch_init_all(bContext *C, wmOperator *op)
static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- Object *obedit = CTX_data_edit_object(C);
if (!stitch_init_all(C, op))
return OPERATOR_CANCELLED;
WM_event_add_modal_handler(C, op);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = scene->toolsettings;
+ const bool synced_selection = (ts->uv_flag & UV_SYNC_SELECTION) != 0;
+
+ StitchStateContainer *ssc = (StitchStateContainer *)op->customdata;
+
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ StitchState *state = ssc->states[ob_index];
+ Object *obedit = state->obedit;
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ if (synced_selection && (em->bm->totvertsel == 0)) {
+ continue;
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ }
+
return OPERATOR_RUNNING_MODAL;
}
static void stitch_exit(bContext *C, wmOperator *op, int finished)
{
- Scene *scene;
- SpaceImage *sima;
+ Scene *scene = CTX_data_scene(C);
+ SpaceImage *sima = CTX_wm_space_image(C);
ScrArea *sa = CTX_wm_area(C);
- scene = CTX_data_scene(C);
- sima = CTX_wm_space_image(C);
-
StitchStateContainer *ssc = (StitchStateContainer *)op->customdata;
- StitchState *state = ssc->states[ssc->active_object_index];
- Object *obedit = state->obedit;
if (finished) {
- int i;
-
RNA_float_set(op->ptr, "limit", ssc->limit_dist);
RNA_boolean_set(op->ptr, "use_limit", ssc->use_limit);
RNA_boolean_set(op->ptr, "snap_islands", ssc->snap_islands);
@@ -2293,24 +2356,41 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
RNA_int_set(op->ptr, "static_island", ssc->static_island);
- /* Store selection for re-execution of stitch */
- /* WIP */
- for (i = 0; i < state->selection_size; i++) {
- UvElement *element;
+ int *objs_selection_count = NULL;
+ objs_selection_count = MEM_mallocN(sizeof(int *) * ssc->objects_len, "objects_selection_count");
+
+ /* Store selection for re-execution of stitch
+ * - Store all selected UVs in "selection"
+ * - Store how many each object has in "objects_selection_count". */
+ RNA_collection_clear(op->ptr, "selection");
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ StitchState *state = ssc->states[ob_index];
+ Object *obedit = state->obedit;
+
PointerRNA itemptr;
- if (ssc->mode == STITCH_VERT) {
- element = state->selection_stack[i];
- }
- else {
- element = ((UvEdge *)state->selection_stack[i])->element;
+ for (int i = 0; i < state->selection_size; i++) {
+ UvElement *element;
+
+ if (ssc->mode == STITCH_VERT) {
+ element = state->selection_stack[i];
+ }
+ else {
+ element = ((UvEdge *)state->selection_stack[i])->element;
+ }
+ RNA_collection_add(op->ptr, "selection", &itemptr);
+
+ RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->l->f));
+ RNA_int_set(&itemptr, "element_index", element->loop_of_poly_index);
}
- RNA_collection_add(op->ptr, "selection", &itemptr);
+ uvedit_live_unwrap_update(sima, scene, obedit);
- RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->l->f));
- RNA_int_set(&itemptr, "element_index", element->loop_of_poly_index);
+ objs_selection_count[ob_index] = state->selection_size;
}
- uvedit_live_unwrap_update(sima, scene, obedit);
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "objects_selection_count");
+ RNA_def_property_array(prop, ssc->objects_len);
+ RNA_int_set_array(op->ptr, "objects_selection_count", objs_selection_count);
+ MEM_freeN(objs_selection_count);
}
if (sa)
@@ -2318,8 +2398,21 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
ED_region_draw_cb_exit(CTX_wm_region(C)->type, ssc->draw_handle);
- DEG_id_tag_update(obedit->data, 0);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ ToolSettings *ts = scene->toolsettings;
+ const bool synced_selection = (ts->uv_flag & UV_SYNC_SELECTION) != 0;
+
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ StitchState *state = ssc->states[ob_index];
+ Object *obedit = state->obedit;
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ if (synced_selection && (em->bm->totvertsel == 0)) {
+ continue;
+ }
+
+ DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ }
state_delete_all(ssc);
@@ -2628,4 +2721,9 @@ void UV_OT_stitch(wmOperatorType *ot)
prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", "");
/* Selection should not be editable or viewed in toolbar */
RNA_def_property_flag(prop, PROP_HIDDEN);
+
+ /* test should not be editable or viewed in toolbar */
+ prop = RNA_def_int_array(ot->srna, "objects_selection_count", 1, NULL, 0, INT_MAX, "objects_selection_count", "objects_selection_count", 0, INT_MAX);
+ RNA_def_property_array(prop, 6);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}