Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/uvedit/uvedit_ops.c
| Context not available. | |||||
| #include "BLI_alloca.h" | #include "BLI_alloca.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_lasso.h" | #include "BLI_lasso.h" | ||||
| #include "BLI_linklist.h" | |||||
| #include "BLI_stack.h" | |||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLI_array.h" | #include "BLI_array.h" | ||||
| Context not available. | |||||
| ot->exec = uv_weld_exec; | ot->exec = uv_weld_exec; | ||||
| ot->poll = ED_operator_uvedit; | ot->poll = ED_operator_uvedit; | ||||
| } | } | ||||
| /* ******************** unstitch operator **************** */ | |||||
| typedef struct UVRip | |||||
| { | |||||
| MLoopUV *uv_side1; | |||||
| MLoopUV *uv_side2; | |||||
| float center1[2]; | |||||
| float center2[2]; | |||||
| float point1[2]; | |||||
| float point2[2]; | |||||
| struct UVRip *next; | |||||
| MLoopUV *uv_next1; | |||||
| MLoopUV *uv_next2; | |||||
| MLoopUV *extend[2]; | |||||
| float extend_center[2]; | |||||
| bool side; | |||||
| } UVRip; | |||||
| static void free_UVRip(void* _current) | |||||
| { | |||||
| UVRip* current = _current; | |||||
| UVRip* next; | |||||
| while (current) { | |||||
| next = current->next; | |||||
| MEM_freeN (current); | |||||
| current = next; | |||||
| } | |||||
| } | |||||
| static int num_lines_crossed(float center1[2], float center2[2], UVRip* previous, UVRip* current) | |||||
| { | |||||
| float slope; | |||||
| float lstart1, lend1, lstart2, lend2; | |||||
| if (center1[0] == center2[0]){ | |||||
| return (((previous->point1[0] <= center1[0] && | |||||
| previous->point2[0] >= center1[0]) || | |||||
| (previous->point1[0] >= center1[0] && | |||||
| previous->point2[0] <= center1[0]) + | |||||
| (current->point1[0] <= center1[0] && | |||||
| current->point2[0] >= center1[0]) || | |||||
| (current->point1[0] >= center1[0] && | |||||
| current->point2[0] <= center1[0])) %2 == 0); | |||||
| } | |||||
| else{ | |||||
| slope = (center2[1] - center1[1]) / (center2[0] - center1[0]); | |||||
| lstart1 = slope * (previous->point1[0] - center1[0]) + center1[1]; | |||||
| lend1 = slope * (previous->point2[0]- center1[0]) + center1[1]; | |||||
| lstart2 = slope * (current->point1[0] - center1[0]) + center1[1]; | |||||
| lend2 = slope * (current->point2[0]- center1[0]) + center1[1]; | |||||
| /* Check how many lines does the center line cross? */ | |||||
| return ((lstart1 <= previous->point1[1] && | |||||
| lend1 >= previous->point2[1]) || | |||||
| (lstart1 >= previous->point1[1] && | |||||
| lend1 <= previous->point2[1]) + | |||||
| (lstart2 <= current->point1[1] && | |||||
| lend2 >= current->point2[1]) || | |||||
| (lstart2 >= current->point1[1] && | |||||
| lend2 <= current->point2[1])); | |||||
| } | |||||
| } | |||||
| static int uv_unstitch_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Object *obedit = CTX_data_edit_object(C); | |||||
| Mesh *me = (Mesh *)obedit->data; | |||||
| BMEditMesh *em = me->edit_btmesh; | |||||
| SpaceImage *sima = CTX_wm_space_image(C); | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| BMFace *efa; | |||||
| BMIter iter, liter; | |||||
| BMLoop *loop; | |||||
| MLoopUV *luv; | |||||
| MLoopUV *prev_luv, *next_luv; | |||||
| LinkNode *connected_UV_LL = NULL; | |||||
| LinkNode *item = NULL; | |||||
| LinkNode *item_inner = NULL; | |||||
| BLI_Stack *link_ends = BLI_stack_new (sizeof(UVRip), __func__); | |||||
| UVRip *previous, *current, *head; | |||||
| float cent[2], co[2]; | |||||
| bool prev, next, new_rip; | |||||
| UVRip *new; | |||||
| RNA_float_get_array(op->ptr, "location", co); | |||||
| const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); | |||||
| BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { | |||||
| uv_poly_center(efa, cent, cd_loop_uv_offset); | |||||
| BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) { | |||||
| luv = BM_ELEM_CD_GET_VOID_P(loop, cd_loop_uv_offset); | |||||
| if (luv->flag & MLOOPUV_VERTSEL) { | |||||
| prev_luv = BM_ELEM_CD_GET_VOID_P(loop->prev, cd_loop_uv_offset); | |||||
| prev = prev_luv->flag & MLOOPUV_VERTSEL; | |||||
| next_luv = BM_ELEM_CD_GET_VOID_P(loop->next, cd_loop_uv_offset); | |||||
| next = next_luv->flag & MLOOPUV_VERTSEL; | |||||
| /* check if edge already registered */ | |||||
| item = connected_UV_LL; | |||||
| previous = NULL; | |||||
| if (next) { | |||||
| /* Edge */ | |||||
| new_rip = true; | |||||
| while (item && new_rip) { | |||||
| current = item->link; | |||||
| while(current && new_rip) { | |||||
| if ((compare_v2v2(current->point1, luv->uv, 0.0f) && | |||||
| compare_v2v2(current->point2, next_luv->uv, 0.0f)) || | |||||
| (compare_v2v2(current->point2, luv->uv, 0.0f) && | |||||
| compare_v2v2(current->point1, next_luv->uv, 0.0f))) | |||||
| { | |||||
| /* same edge */ | |||||
| if (current->uv_side1 != NULL) { | |||||
| current->uv_side2 = luv; | |||||
| current->uv_next2 = next_luv; | |||||
| copy_v2_v2(current->center2, cent); | |||||
| } | |||||
| else { | |||||
| current->uv_side1 = luv; | |||||
| current->uv_next1 = next_luv; | |||||
| copy_v2_v2(current->center1, cent); | |||||
| } | |||||
| new_rip = false; | |||||
| } | |||||
| else{ | |||||
| previous = current; | |||||
| current = current->next; | |||||
| } | |||||
| } | |||||
| if (!current) | |||||
| BLI_stack_push(link_ends, previous); | |||||
| head = item->link; | |||||
| item = item->next; | |||||
| } | |||||
| /* Link to back */ | |||||
| item_inner = connected_UV_LL; | |||||
| while(new_rip && !BLI_stack_is_empty(link_ends)) { | |||||
| BLI_stack_pop(link_ends, previous); | |||||
| if (new_rip && | |||||
| (compare_v2v2(previous->point2, luv->uv, 0.0f) || | |||||
| compare_v2v2(previous->point2, next_luv->uv, 0.0f))) | |||||
| { | |||||
| /* Create new rip */ | |||||
| new = MEM_mallocN(sizeof(UVRip), "unstitch UV element and distance data"); | |||||
| new->next = NULL; | |||||
| new_rip = false; | |||||
| float center[2]; | |||||
| bool side; | |||||
| if(previous->uv_side1 != NULL){ | |||||
| side = true; | |||||
| copy_v2_v2(center, previous->center1); | |||||
| } | |||||
| else{ | |||||
| side = false; | |||||
| copy_v2_v2(center, previous->center2); | |||||
| } | |||||
| if (compare_v2v2(previous->point2, luv->uv, 0.0f)) { | |||||
| copy_v2_v2(new->point1, luv->uv); | |||||
| copy_v2_v2(new->point2, next_luv->uv); | |||||
| } | |||||
| else { | |||||
| copy_v2_v2(new->point1, next_luv->uv); | |||||
| copy_v2_v2(new->point2, luv->uv); | |||||
| } | |||||
| /* Check how many lines it crosses */ | |||||
| if ((num_lines_crossed(center, cent, previous, new) % 2 == 0 && side) || | |||||
| (!num_lines_crossed(center, cent, previous, new) % 2 == 0 && !side)) | |||||
| { | |||||
| /* same side */ | |||||
| new->uv_side1 = luv; | |||||
| new->uv_next1 = next_luv; | |||||
| new->uv_side2 = NULL; | |||||
| new->uv_next2 = NULL; | |||||
| copy_v2_v2(new->center1, cent); | |||||
| } | |||||
| else { | |||||
| /* other side */ | |||||
| new->uv_side1 = NULL; | |||||
| new->uv_next1 = NULL; | |||||
| new->uv_side2 = luv; | |||||
| new->uv_next2 = next_luv; | |||||
| copy_v2_v2(new->center2, cent); | |||||
| } | |||||
| previous->next = new; | |||||
| } else { | |||||
| item_inner = item_inner->next; | |||||
| } | |||||
| } | |||||
| head = item_inner->link; | |||||
| BLI_stack_clear(link_ends); | |||||
| /* New link */ | |||||
| if (new_rip) { | |||||
| new = MEM_mallocN(sizeof(UVRip), "unstitch UV element and distance data"); | |||||
| new->next = NULL; | |||||
| new->uv_side1 = luv; | |||||
| new->uv_next1 = next_luv; | |||||
| new->uv_side2 = NULL; | |||||
| new->uv_next2 = NULL; | |||||
| copy_v2_v2(new->point1, luv->uv); | |||||
| copy_v2_v2(new->point2, next_luv->uv); | |||||
| copy_v2_v2(new->center1, cent); | |||||
| BLI_linklist_prepend(&connected_UV_LL, new); | |||||
| head = new; | |||||
| } | |||||
| /* Link to front */ | |||||
| if (new != NULL) { | |||||
| new->extend[0] = NULL; | |||||
| new->extend[1] = NULL; | |||||
| item_inner = connected_UV_LL; | |||||
| LinkNode* nprevious = NULL; | |||||
| while (item_inner) { | |||||
| current = item_inner->link; | |||||
| if (current != head && | |||||
| (compare_v2v2(new->point2, current->point1, 0.0f) || | |||||
| (new == head && (compare_v2v2(new->point1, current->point1, 0.0f))))) | |||||
| { | |||||
| /* find out which side it's on */ | |||||
| float center[2]; | |||||
| bool side= true; | |||||
| if (new->center1 != NULL) { | |||||
| side = true; | |||||
| copy_v2_v2(center, current->center1); | |||||
| } | |||||
| else { | |||||
| side = false; | |||||
| copy_v2_v2(center, current->center2); | |||||
| } | |||||
| if (compare_v2v2(new->point1, current->point1, 0.0f)) { | |||||
| float temp[2]; | |||||
| copy_v2_v2(temp, new->point2); | |||||
| copy_v2_v2(new->point2, new->point1); | |||||
| copy_v2_v2(new->point1, temp); | |||||
| } | |||||
| /* Check how many lines it crosses */ | |||||
| if ((num_lines_crossed(cent, center, new, current) % 2 == 0 && !side) || | |||||
| (!num_lines_crossed(cent, center, new, current) % 2 == 0 && side)) | |||||
| { | |||||
| /* Flip them! */ | |||||
| float temp[2]; | |||||
| MLoopUV* temp_luv; | |||||
| while (current) { | |||||
| temp_luv = current->uv_side1; | |||||
| current->uv_side1 = current->uv_side2; | |||||
| current->uv_side2 = temp_luv; | |||||
| temp_luv = current->uv_next1; | |||||
| current->uv_next1 = current->uv_next2; | |||||
| current->uv_next2 = temp_luv; | |||||
| copy_v2_v2(temp, current->center1); | |||||
| copy_v2_v2(current->center1, current->center2); | |||||
| copy_v2_v2(current->center2, temp); | |||||
| current = current->next; | |||||
| } | |||||
| } | |||||
| new->next = item_inner->link; | |||||
| if (nprevious) { | |||||
| nprevious->next = item_inner->next; | |||||
| } | |||||
| else { | |||||
| connected_UV_LL = item_inner->next; | |||||
| } | |||||
| MEM_freeN (item_inner); | |||||
| item_inner = NULL; | |||||
| } | |||||
| else { | |||||
| nprevious = item_inner; | |||||
| item_inner = item_inner->next; | |||||
| } | |||||
| } | |||||
| new = NULL; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /* Ripping the edges */ | |||||
| bool side = true; | |||||
| float side_avg = 0; | |||||
| float rip[2]; | |||||
| float number_of = 0; | |||||
| for (item = connected_UV_LL; item; item = item->next) { | |||||
| /* Decide the point to rip from */ | |||||
| previous = item->link; | |||||
| current = item->link; | |||||
| while (previous->next){ | |||||
| previous = previous->next; | |||||
| } | |||||
| /* check if it is a loop. */ | |||||
| if (compare_v2v2(previous->point2, current->point1, 0.0f)) { | |||||
| /* ripping from center */ | |||||
| rip[0] = 0; | |||||
| rip[1] = 0; | |||||
| while (current) { | |||||
| add_v2_v2(rip, current->point1); | |||||
| number_of++; | |||||
| current = current->next; | |||||
| } | |||||
| mul_v2_v2fl(rip, rip, 1.0f / number_of); | |||||
| number_of = 0; | |||||
| } | |||||
| else{ | |||||
| /* ripping towards mouse */ | |||||
| rip[0] = co[0]; | |||||
| rip[1] = co[1]; | |||||
| } | |||||
| current = item->link; | |||||
| while (current) { | |||||
| if (current->center1 != NULL && current->center2 != NULL) { | |||||
| side_avg += len_manhattan_v2v2(current->center1, rip) < len_manhattan_v2v2(current->center2, rip); | |||||
| } | |||||
| number_of++; | |||||
| current = current->next; | |||||
| } | |||||
| side = (int)((side_avg / number_of) + 0.5); | |||||
| /* rip the side */ | |||||
| current = item->link; | |||||
| while (current) { | |||||
| /* I'm not supporting "Keep UV and edit mode mesh selection in sync." | |||||
| * I can't see how such an option would work with this feature. | |||||
| */ | |||||
| if (side) { | |||||
| if (current->uv_side2 != NULL) { | |||||
| current->uv_side2->flag &= ~MLOOPUV_VERTSEL; | |||||
| current->uv_next2->flag &= ~MLOOPUV_VERTSEL; | |||||
| } | |||||
| } | |||||
| else { | |||||
| if (current->uv_side1 != NULL) { | |||||
| current->uv_side1->flag &= ~MLOOPUV_VERTSEL; | |||||
| current->uv_next1->flag &= ~MLOOPUV_VERTSEL; | |||||
| } | |||||
| } | |||||
| current = current->next; | |||||
| } | |||||
| } | |||||
| /* Second pass. Now we deal with the verts */ | |||||
| bool list_loop; | |||||
| float rip_distance; | |||||
| BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { | |||||
| uv_poly_center(efa, cent, cd_loop_uv_offset); | |||||
| BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) { | |||||
| luv = BM_ELEM_CD_GET_VOID_P(loop, cd_loop_uv_offset); | |||||
| if (luv->flag & MLOOPUV_VERTSEL) { | |||||
| prev_luv = BM_ELEM_CD_GET_VOID_P(loop->prev, cd_loop_uv_offset); | |||||
| prev = prev_luv->flag & MLOOPUV_VERTSEL; | |||||
| next_luv = BM_ELEM_CD_GET_VOID_P(loop->next, cd_loop_uv_offset); | |||||
| next = next_luv->flag & MLOOPUV_VERTSEL; | |||||
| if (!prev && !next) { | |||||
| item = connected_UV_LL; | |||||
| new_rip = true; | |||||
| while (item && new_rip) { | |||||
| current = item->link; | |||||
| previous = current; | |||||
| while (previous->next){ | |||||
| previous = previous->next; | |||||
| } | |||||
| list_loop = compare_v2v2(previous->point2, current->point1, 0.0f); | |||||
| if (side) { | |||||
| copy_v2_v2(rip,current->center1); | |||||
| }else{ | |||||
| copy_v2_v2(rip,current->center2); | |||||
| } | |||||
| /* Start */ | |||||
| rip_distance = len_manhattan_v2v2(cent, rip); | |||||
| if (compare_v2v2(current->point1, luv->uv, 0.0f)) { | |||||
| new_rip = false; | |||||
| if (compare_v2v2(current->point2, current->point1, 0.0f)) { | |||||
| /* Single vert */ | |||||
| rip_distance = len_manhattan_v2v2(cent, co); | |||||
| if (!current->extend[0]) { | |||||
| current->extend[0] = luv; | |||||
| current->extend_center[0] = rip_distance; | |||||
| } | |||||
| else if (!current->extend[1]) { | |||||
| if (current->extend_center[0] < rip_distance) { | |||||
| current->extend[1] = luv; | |||||
| current->extend_center[1] = rip_distance; | |||||
| } | |||||
| else { | |||||
| current->extend[1] = current->extend[0]; | |||||
| current->extend_center[1] = current->extend_center[0]; | |||||
| current->extend[0] = luv; | |||||
| current->extend_center[0] = rip_distance; | |||||
| } | |||||
| } | |||||
| else if (current->extend_center[0] < rip_distance) { | |||||
| if (current->extend_center[1] < rip_distance) { | |||||
| luv->flag &= ~MLOOPUV_VERTSEL; | |||||
| new->side = false; | |||||
| } | |||||
| else { | |||||
| current->extend[1]->flag &= ~MLOOPUV_VERTSEL; | |||||
| current->extend[1] = luv; | |||||
| current->extend_center[1] = rip_distance; | |||||
| new->side = false; | |||||
| } | |||||
| } | |||||
| else { | |||||
| current->extend[1]->flag &= ~MLOOPUV_VERTSEL; | |||||
| current->extend[1] = current->extend[0]; | |||||
| current->extend_center[1] = current->extend_center[0]; | |||||
| current->extend[0] = luv; | |||||
| current->extend_center[0] = rip_distance; | |||||
| new->side = false; | |||||
| } | |||||
| } | |||||
| else if (list_loop) { | |||||
| luv->flag &= ~MLOOPUV_VERTSEL; | |||||
| } | |||||
| else if (!current->extend[0]) { | |||||
| current->extend[0] = luv; | |||||
| current->extend_center[0] = rip_distance; | |||||
| } | |||||
| else if (current->extend_center[0] < rip_distance) { | |||||
| luv->flag &= ~MLOOPUV_VERTSEL; | |||||
| } | |||||
| else { | |||||
| current->extend[0]->flag &= ~MLOOPUV_VERTSEL; | |||||
| current->extend[0] = luv; | |||||
| current->extend_center[0] = rip_distance; | |||||
| } | |||||
| } | |||||
| /* middle */ | |||||
| previous = current; | |||||
| current = current->next; | |||||
| while(current && new_rip) { | |||||
| if (compare_v2v2(current->point1, luv->uv, 0.0f)) { | |||||
| bool corner = false; | |||||
| float center_start[2]; | |||||
| if (side){ | |||||
| copy_v2_v2(center_start, current->center2); | |||||
| } | |||||
| else{ | |||||
| copy_v2_v2(center_start, current->center1); | |||||
| } | |||||
| corner = (num_lines_crossed(center_start, cent, previous, current) % 2) != 0; | |||||
| if (!corner) { | |||||
| luv->flag &= ~MLOOPUV_VERTSEL; | |||||
| } | |||||
| new_rip = false; | |||||
| } | |||||
| else{ | |||||
| previous = current; | |||||
| current = current->next; | |||||
| } | |||||
| } | |||||
| if (side){ | |||||
| copy_v2_v2(rip,previous->center1); | |||||
| }else{ | |||||
| copy_v2_v2(rip,previous->center2); | |||||
| } | |||||
| rip_distance = len_manhattan_v2v2(cent, rip); | |||||
| /* End*/ | |||||
| if (new_rip && !list_loop && compare_v2v2(previous->point2, luv->uv, 0.0f)){ | |||||
| new_rip = false; | |||||
| if (!previous->extend[1]) { | |||||
| previous->extend[1] = luv; | |||||
| previous->extend_center[1] = rip_distance; | |||||
| } | |||||
| else if (previous->extend_center[1] < rip_distance){ | |||||
| luv->flag &= ~MLOOPUV_VERTSEL; | |||||
| } | |||||
| else{ | |||||
| previous->extend[1]->flag &= ~MLOOPUV_VERTSEL; | |||||
| previous->extend[1] = luv; | |||||
| previous->extend_center[1] = rip_distance; | |||||
| } | |||||
| } | |||||
| item = item->next; | |||||
| } | |||||
| rip_distance = len_manhattan_v2v2(cent, co); | |||||
| if (new_rip){ | |||||
| new = MEM_mallocN(sizeof(UVRip), "unstitch UV element and distance data"); | |||||
| new->extend[0] = luv; | |||||
| new->extend[1] = NULL; | |||||
| new->extend_center[0] = rip_distance; | |||||
| new->next = NULL; | |||||
| new->uv_side1 = luv; | |||||
| new->uv_next1 = NULL; | |||||
| new->uv_side2 = NULL; | |||||
| new->uv_next2 = NULL; | |||||
| new->side = true; | |||||
| copy_v2_v2(new->point1, luv->uv); | |||||
| copy_v2_v2(new->point2, luv->uv); | |||||
| BLI_linklist_prepend(&connected_UV_LL, new); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /* Deal with single verts */ | |||||
| item = connected_UV_LL; | |||||
| while (item) { | |||||
| current = item->link; | |||||
| if (compare_v2v2(current->point2, current->point1, 0.0f) && | |||||
| current->side && current->extend[1]) | |||||
| { | |||||
| current->extend[1]->flag &= ~MLOOPUV_VERTSEL; | |||||
| } | |||||
| item = item->next; | |||||
| } | |||||
| /* Clean up */ | |||||
| BLI_stack_free(link_ends); | |||||
| BLI_linklist_free(connected_UV_LL, (LinkNodeFreeFP)free_UVRip); | |||||
| uvedit_live_unwrap_update(sima, scene, obedit); | |||||
| DAG_id_tag_update(obedit->data, 0); | |||||
| WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static int uv_unstitch_invoke(bContext *C, wmOperator *op, const wmEvent *event) | |||||
| { | |||||
| ARegion *ar = CTX_wm_region(C); | |||||
| float co[2]; | |||||
| UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); | |||||
| RNA_float_set_array(op->ptr, "location", co); | |||||
| return uv_unstitch_exec(C, op); | |||||
| } | |||||
| static void UV_OT_unstitch(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Unstitch"; | |||||
| ot->description = "Unstitch selected UV vertices"; | |||||
| ot->idname = "UV_OT_unstitch"; | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| /* api callbacks */ | |||||
| ot->exec = uv_unstitch_exec; | |||||
| ot->invoke = uv_unstitch_invoke; | |||||
| ot->poll = ED_operator_uvedit; | |||||
| /* translation data */ | |||||
| Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR_DUMMY); | |||||
| /* properties */ | |||||
| RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, | |||||
| "Location", "Mouse location in normalized coordinates, 0.0 to 1.0 is within the image bounds", -100.0f, 100.0f); | |||||
| } | |||||
| /* ******************** (de)select all operator **************** */ | /* ******************** (de)select all operator **************** */ | ||||
| Context not available. | |||||
| WM_operatortype_append(UV_OT_seams_from_islands); | WM_operatortype_append(UV_OT_seams_from_islands); | ||||
| WM_operatortype_append(UV_OT_mark_seam); | WM_operatortype_append(UV_OT_mark_seam); | ||||
| WM_operatortype_append(UV_OT_weld); | WM_operatortype_append(UV_OT_weld); | ||||
| WM_operatortype_append(UV_OT_unstitch); | |||||
| WM_operatortype_append(UV_OT_remove_doubles); | WM_operatortype_append(UV_OT_remove_doubles); | ||||
| WM_operatortype_append(UV_OT_pin); | WM_operatortype_append(UV_OT_pin); | ||||
| Context not available. | |||||
| WM_operatortype_append(UV_OT_tile_set); | WM_operatortype_append(UV_OT_tile_set); | ||||
| } | } | ||||
| void ED_operatormacros_uvedit(void) | |||||
| { | |||||
| wmOperatorType *ot; | |||||
| wmOperatorTypeMacro *otmacro; | |||||
| ot = WM_operatortype_append_macro("UV_OT_unstitch_move", "unstitch", "unstitch UV's and move the result", | |||||
| OPTYPE_UNDO | OPTYPE_REGISTER); | |||||
| otmacro = WM_operatortype_macro_define(ot, "UV_OT_unstitch"); | |||||
| RNA_boolean_set(otmacro->ptr, "use_fill", false); | |||||
| otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); | |||||
| RNA_enum_set(otmacro->ptr, "proportional", 0); | |||||
| RNA_boolean_set(otmacro->ptr, "mirror", false); | |||||
| } | |||||
| void ED_keymap_uvedit(wmKeyConfig *keyconf) | void ED_keymap_uvedit(wmKeyConfig *keyconf) | ||||
| { | { | ||||
| wmKeyMap *keymap; | wmKeyMap *keymap; | ||||
| Context not available. | |||||
| WM_keymap_add_item(keymap, "UV_OT_select_pinned", PKEY, KM_PRESS, KM_SHIFT, 0); | WM_keymap_add_item(keymap, "UV_OT_select_pinned", PKEY, KM_PRESS, KM_SHIFT, 0); | ||||
| WM_keymap_add_menu(keymap, "IMAGE_MT_uvs_weldalign", WKEY, KM_PRESS, 0, 0); | WM_keymap_add_menu(keymap, "IMAGE_MT_uvs_weldalign", WKEY, KM_PRESS, 0, 0); | ||||
| /* uv operations */ | /* uv operations */ | ||||
| WM_keymap_add_item(keymap, "UV_OT_stitch", VKEY, KM_PRESS, 0, 0); | WM_keymap_add_item(keymap, "UV_OT_stitch", VKEY, KM_PRESS, 0, 0); | ||||
| WM_keymap_add_item(keymap, "UV_OT_unstitch_move", UKEY, KM_PRESS, 0, 0); | |||||
| kmi = WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, 0, 0); | kmi = WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, 0, 0); | ||||
| RNA_boolean_set(kmi->ptr, "clear", false); | RNA_boolean_set(kmi->ptr, "clear", false); | ||||
| kmi = WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, KM_ALT, 0); | kmi = WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, KM_ALT, 0); | ||||
| Context not available. | |||||