diff options
author | Campbell Barton <ideasman42@gmail.com> | 2008-05-08 20:33:55 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2008-05-08 20:33:55 +0400 |
commit | 8fdc367e0d0f7edc341af7a1de4302bf46a051fd (patch) | |
tree | b1610ebecfdf70058a31b83013cf1bd64e32a682 /source | |
parent | 3faf12770700a87eec348868b3c53d3080b6739e (diff) |
2.46 todo item, added back seam marking tools from UV-face mode.
Since these conflict with loop select its now an option from the mesh tools panel. also made it possible to alt+rmb and alt+shift+rmb to mark other edge flags (creases,
bevel weights, sharp edges)
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/include/BDR_editface.h | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 11 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 4 | ||||
-rw-r--r-- | source/blender/src/editface.c | 205 | ||||
-rw-r--r-- | source/blender/src/editmesh_mods.c | 118 |
5 files changed, 214 insertions, 129 deletions
diff --git a/source/blender/include/BDR_editface.h b/source/blender/include/BDR_editface.h index fb6b65c3972..58b344981ca 100644 --- a/source/blender/include/BDR_editface.h +++ b/source/blender/include/BDR_editface.h @@ -32,6 +32,7 @@ struct MTFace; struct EditFace; +struct EditEdge; struct Mesh; struct MCol; @@ -53,6 +54,8 @@ void uv_autocalc_tface(void); void set_texturepaint(void); void get_same_uv(void); void seam_mark_clear_tface(short mode); - +int edgetag_shortest_path(struct EditEdge *source, struct EditEdge *target); +void edgetag_context_set(struct EditEdge *eed, int val); +int edgetag_context_check(struct EditEdge *eed); #endif /* BDR_EDITFACE_H */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index e0e8c351d2c..45833695ffe 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -437,7 +437,9 @@ typedef struct ToolSettings { char skgen_postpro_passes; char skgen_subdivisions[3]; - char pad3[5]; + /* Alt+RMB option */ + char edge_mode; + char pad3[4]; } ToolSettings; /* Used by all brushes to store their properties, which can be directly set @@ -783,6 +785,13 @@ typedef struct Scene { #define UVCALC_FILLHOLES 1 #define UVCALC_NO_ASPECT_CORRECT 2 /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */ +/* toolsettings->edge_mode */ +#define EDGE_MODE_SELECT 0 +#define EDGE_MODE_TAG_SEAM 1 +#define EDGE_MODE_TAG_SHARP 2 +#define EDGE_MODE_TAG_CREASE 3 +#define EDGE_MODE_TAG_BEVEL 4 + /* toolsettings->particle flag */ #define PE_KEEP_LENGTHS 1 #define PE_LOCK_FIRST 2 diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index b02e89233e5..94a715162a0 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -5070,6 +5070,10 @@ static void editing_panel_mesh_tools1(Object *ob, Mesh *me) uiBlockEndAlign(block); + uiDefButBitS(block, TOG, B_MESH_X_MIRROR, B_DIFF, "X-axis mirror",1125,0,150,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "While using transforms, mirrors the transformation"); + + uiDefButC(block, MENU, REDRAWBUTSEDIT, "Edge Alt-Select Mode%t|Loop Select%x0|Tag Edges (Seam)%x1|Tag Edges (Sharp)%x2|Tag Edges (Sharp)%x3|Tag Edges (Bevel)%x4",1125,88,150,19, &G.scene->toolsettings->edge_mode, 0, 0, 0, 0, "Operation to use when Alt+RMB on edges, Use Alt+Shift+RMB to tag the shortest path from the active edge"); + uiBlockBeginAlign(block); uiDefButBitI(block, TOG, G_ALLEDGES, 0, "All Edges", 1125, 22,150,19, &G.f, 0, 0, 0, 0, "Displays all edges in object mode without optimization"); uiDefButBitS(block, TOG, B_MESH_X_MIRROR, B_DIFF, "X-axis mirror",1125,0,150,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "While using transforms, mirrors the transformation"); diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c index c1665332be8..e74401cb622 100644 --- a/source/blender/src/editface.c +++ b/source/blender/src/editface.c @@ -870,14 +870,14 @@ int minmax_tface(float *min, float *max) return ok; } -#define ME_SEAM_DONE ME_SEAM_LAST /* reuse this flag */ +#define ME_SEAM_DONE 2 /* reuse this flag */ -static float seam_cut_cost(Mesh *me, int e1, int e2, int vert) +static float edgetag_cut_cost(EditMesh *em, int e1, int e2, int vert) { - MVert *v = me->mvert + vert; - MEdge *med1 = me->medge + e1, *med2 = me->medge + e2; - MVert *v1 = me->mvert + ((med1->v1 == vert)? med1->v2: med1->v1); - MVert *v2 = me->mvert + ((med2->v1 == vert)? med2->v2: med2->v1); + EditVert *v = EM_get_vert_for_index(vert); + EditEdge *eed1 = EM_get_edge_for_index(e1), *eed2 = EM_get_edge_for_index(e2); + EditVert *v1 = EM_get_vert_for_index( (eed1->v1->tmp.l == vert)? eed1->v2->tmp.l: eed1->v1->tmp.l ); + EditVert *v2 = EM_get_vert_for_index( (eed2->v1->tmp.l == vert)? eed2->v2->tmp.l: eed2->v1->tmp.l ); float cost, d1[3], d2[3]; cost = VecLenf(v1->co, v->co); @@ -891,19 +891,19 @@ static float seam_cut_cost(Mesh *me, int e1, int e2, int vert) return cost; } -static void seam_add_adjacent(Mesh *me, Heap *heap, int mednum, int vertnum, int *nedges, int *edges, int *prevedge, float *cost) +static void edgetag_add_adjacent(EditMesh *em, Heap *heap, int mednum, int vertnum, int *nedges, int *edges, int *prevedge, float *cost) { int startadj, endadj = nedges[vertnum+1]; for (startadj = nedges[vertnum]; startadj < endadj; startadj++) { int adjnum = edges[startadj]; - MEdge *medadj = me->medge + adjnum; + EditEdge *eedadj = EM_get_edge_for_index(adjnum); float newcost; - if (medadj->flag & ME_SEAM_DONE) + if (eedadj->f2 & ME_SEAM_DONE) continue; - newcost = cost[mednum] + seam_cut_cost(me, mednum, adjnum, vertnum); + newcost = cost[mednum] + edgetag_cut_cost(em, mednum, adjnum, vertnum); if (cost[adjnum] > newcost) { cost[adjnum] = newcost; @@ -913,59 +913,93 @@ static void seam_add_adjacent(Mesh *me, Heap *heap, int mednum, int vertnum, int } } -static int seam_shortest_path(Mesh *me, int source, int target) +void edgetag_context_set(EditEdge *eed, int val) { + switch (G.scene->toolsettings->edge_mode) { + case EDGE_MODE_TAG_SEAM: + if (val) {eed->seam = 255;} + else {eed->seam = 0;} + break; + case EDGE_MODE_TAG_SHARP: + if (val) {eed->sharp = 1;} + else {eed->sharp = 0;} + break; + case EDGE_MODE_TAG_CREASE: + if (val) {eed->crease = 1.0f;} + else {eed->crease = 0.0f;} + break; + case EDGE_MODE_TAG_BEVEL: + if (val) {eed->bweight = 1.0f;} + else {eed->bweight = 0.0f;} + break; + } +} + +int edgetag_context_check(EditEdge *eed) +{ + switch (G.scene->toolsettings->edge_mode) { + case EDGE_MODE_TAG_SEAM: + return eed->seam ? 1 : 0; + case EDGE_MODE_TAG_SHARP: + return eed->sharp ? 1 : 0; + case EDGE_MODE_TAG_CREASE: + return eed->crease ? 1 : 0; + case EDGE_MODE_TAG_BEVEL: + return eed->bweight ? 1 : 0; + } + return 0; +} + + +int edgetag_shortest_path(EditEdge *source, EditEdge *target) +{ + EditMesh *em = G.editMesh; + EditEdge *eed; + EditVert *ev; + Heap *heap; EdgeHash *ehash; float *cost; - MEdge *med; - int a, *nedges, *edges, *prevedge, mednum = -1, nedgeswap = 0; - MFace *mf; + int a, totvert=0, totedge=0, *nedges, *edges, *prevedge, mednum = -1, nedgeswap = 0; - /* mark hidden edges as done, so we don't use them */ - ehash = BLI_edgehash_new(); - for (a=0, mf=me->mface; a<me->totface; a++, mf++) { - if (!(mf->flag & ME_HIDE)) { - BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL); - BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL); - if (mf->v4) { - BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL); - BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL); - } - else - BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL); - } + /* we need the vert */ + for (ev= em->verts.first, totvert=0; ev; ev= ev->next) { + ev->tmp.l = totvert; + totvert++; } - for (a=0, med=me->medge; a<me->totedge; a++, med++) - if (!BLI_edgehash_haskey(ehash, med->v1, med->v2)) - med->flag |= ME_SEAM_DONE; - - BLI_edgehash_free(ehash, NULL); + for (eed= em->edges.first; eed; eed = eed->next) { + eed->f2 = 0; + if (eed->h) { + eed->f2 |= ME_SEAM_DONE; + } + eed->tmp.l = totedge; + totedge++; + } /* alloc */ - nedges = MEM_callocN(sizeof(*nedges)*me->totvert+1, "SeamPathNEdges"); - edges = MEM_mallocN(sizeof(*edges)*me->totedge*2, "SeamPathEdges"); - prevedge = MEM_mallocN(sizeof(*prevedge)*me->totedge, "SeamPathPrevious"); - cost = MEM_mallocN(sizeof(*cost)*me->totedge, "SeamPathCost"); + nedges = MEM_callocN(sizeof(*nedges)*totvert+1, "SeamPathNEdges"); + edges = MEM_mallocN(sizeof(*edges)*totedge*2, "SeamPathEdges"); + prevedge = MEM_mallocN(sizeof(*prevedge)*totedge, "SeamPathPrevious"); + cost = MEM_mallocN(sizeof(*cost)*totedge, "SeamPathCost"); /* count edges, compute adjacent edges offsets and fill adjacent edges */ - for (a=0, med=me->medge; a<me->totedge; a++, med++) { - nedges[med->v1+1]++; - nedges[med->v2+1]++; + for (eed= em->edges.first; eed; eed = eed->next) { + nedges[eed->v1->tmp.l+1]++; + nedges[eed->v2->tmp.l+1]++; } - for (a=1; a<me->totvert; a++) { + for (a=1; a<totvert; a++) { int newswap = nedges[a+1]; nedges[a+1] = nedgeswap + nedges[a]; nedgeswap = newswap; } nedges[0] = nedges[1] = 0; - for (a=0, med=me->medge; a<me->totedge; a++, med++) { - edges[nedges[med->v1+1]++] = a; - edges[nedges[med->v2+1]++] = a; + for (a=0, eed= em->edges.first; eed; a++, eed = eed->next) { + edges[nedges[eed->v1->tmp.l+1]++] = a; + edges[nedges[eed->v2->tmp.l+1]++] = a; cost[a] = 1e20f; prevedge[a] = -1; @@ -973,100 +1007,74 @@ static int seam_shortest_path(Mesh *me, int source, int target) /* regular dijkstra shortest path, but over edges instead of vertices */ heap = BLI_heap_new(); - BLI_heap_insert(heap, 0.0f, SET_INT_IN_POINTER(source)); - cost[source] = 0.0f; + BLI_heap_insert(heap, 0.0f, SET_INT_IN_POINTER(source->tmp.l)); + cost[source->tmp.l] = 0.0f; + + EM_init_index_arrays(1, 1, 0); + while (!BLI_heap_empty(heap)) { mednum = GET_INT_FROM_POINTER(BLI_heap_popmin(heap)); - med = me->medge + mednum; + eed = EM_get_edge_for_index( mednum ); - if (mednum == target) + if (mednum == target->tmp.l) break; - if (med->flag & ME_SEAM_DONE) + if (eed->f2 & ME_SEAM_DONE) continue; - med->flag |= ME_SEAM_DONE; + eed->f2 |= ME_SEAM_DONE; - seam_add_adjacent(me, heap, mednum, med->v1, nedges, edges, prevedge, cost); - seam_add_adjacent(me, heap, mednum, med->v2, nedges, edges, prevedge, cost); + edgetag_add_adjacent(em, heap, mednum, eed->v1->tmp.l, nedges, edges, prevedge, cost); + edgetag_add_adjacent(em, heap, mednum, eed->v2->tmp.l, nedges, edges, prevedge, cost); } + MEM_freeN(nedges); MEM_freeN(edges); MEM_freeN(cost); BLI_heap_free(heap, NULL); - for (a=0, med=me->medge; a<me->totedge; a++, med++) - med->flag &= ~ME_SEAM_DONE; + for (eed= em->edges.first; eed; eed = eed->next) { + eed->f2 &= ~ME_SEAM_DONE; + } - if (mednum != target) { + if (mednum != target->tmp.l) { MEM_freeN(prevedge); + EM_free_index_arrays(); return 0; } /* follow path back to source and mark as seam */ - if (mednum == target) { + if (mednum == target->tmp.l) { short allseams = 1; - mednum = target; + mednum = target->tmp.l; do { - med = me->medge + mednum; - if (!(med->flag & ME_SEAM)) { + eed = EM_get_edge_for_index( mednum ); + if (!edgetag_context_check(eed)) { allseams = 0; break; } mednum = prevedge[mednum]; - } while (mednum != source); + } while (mednum != source->tmp.l); - mednum = target; + mednum = target->tmp.l; do { - med = me->medge + mednum; + eed = EM_get_edge_for_index( mednum ); if (allseams) - med->flag &= ~ME_SEAM; + edgetag_context_set(eed, 0); else - med->flag |= ME_SEAM; + edgetag_context_set(eed, 1); mednum = prevedge[mednum]; } while (mednum != -1); } MEM_freeN(prevedge); + EM_free_index_arrays(); return 1; } -static void seam_select(Mesh *me, short *mval, short path) -{ - unsigned int index = 0; - MEdge *medge, *med; - int a, lastindex = -1; - - if (!facesel_edge_pick(me, mval, &index)) - return; - - for (a=0, med=me->medge; a<me->totedge; a++, med++) { - if (med->flag & ME_SEAM_LAST) { - lastindex = a; - med->flag &= ~ME_SEAM_LAST; - break; - } - } - - medge = me->medge + index; - if (!path || (lastindex == -1) || (index == lastindex) || - !seam_shortest_path(me, lastindex, index)) - medge->flag ^= ME_SEAM; - medge->flag |= ME_SEAM_LAST; - - G.f |= G_DRAWSEAMS; - - if (G.rt == 8) - unwrap_lscm(1); - - BIF_undo_push("Mark Seam"); - - object_tface_flags_changed(OBACT, 1); -} - void seam_edgehash_insert_face(EdgeHash *ehash, MFace *mf) { BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL); @@ -1154,11 +1162,6 @@ void face_select() me = get_mesh(ob); getmouseco_areawin(mval); - if (G.qual & LR_ALTKEY) { - seam_select(me, mval, (G.qual & LR_SHIFTKEY) != 0); - return; - } - if (!facesel_face_pick(me, mval, &index, 1)) return; msel= (((MFace*)me->mface)+index); diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index d1873d1fe56..84971e8ce0b 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -92,6 +92,7 @@ editmesh_mods.c, UI level access, no geometry changes #include "BDR_drawobject.h" #include "BDR_editobject.h" +#include "BDR_editface.h" #include "BSE_drawview.h" #include "BSE_edit.h" @@ -2062,6 +2063,7 @@ void loop_multiselect(int looptype) /* ***************** MAIN MOUSE SELECTION ************** */ /* just to have the functions nice together */ + static void mouse_mesh_loop(void) { EditEdge *eed; @@ -2070,36 +2072,100 @@ static void mouse_mesh_loop(void) eed= findnearestedge(&dist); if(eed) { + if (G.scene->toolsettings->edge_mode == EDGE_MODE_SELECT) { + if((G.qual & LR_SHIFTKEY)==0) EM_clear_flag_all(SELECT); - if((G.qual & LR_SHIFTKEY)==0) EM_clear_flag_all(SELECT); - - if((eed->f & SELECT)==0) select=1; - else if(G.qual & LR_SHIFTKEY) select=0; + if((eed->f & SELECT)==0) select=1; + else if(G.qual & LR_SHIFTKEY) select=0; - if(G.scene->selectmode & SCE_SELECT_FACE) { - faceloop_select(eed, select); - } - else if(G.scene->selectmode & SCE_SELECT_EDGE) { - if(G.qual == (LR_CTRLKEY | LR_ALTKEY) || G.qual == (LR_CTRLKEY | LR_ALTKEY |LR_SHIFTKEY)) - edgering_select(eed, select); - else if(G.qual & LR_ALTKEY) - edgeloop_select(eed, select); - } - else if(G.scene->selectmode & SCE_SELECT_VERTEX) { - if(G.qual == (LR_CTRLKEY | LR_ALTKEY) || G.qual == (LR_CTRLKEY | LR_ALTKEY |LR_SHIFTKEY)) - edgering_select(eed, select); - else if(G.qual & LR_ALTKEY) - edgeloop_select(eed, select); - } + if(G.scene->selectmode & SCE_SELECT_FACE) { + faceloop_select(eed, select); + } + else if(G.scene->selectmode & SCE_SELECT_EDGE) { + if(G.qual == (LR_CTRLKEY | LR_ALTKEY) || G.qual == (LR_CTRLKEY | LR_ALTKEY |LR_SHIFTKEY)) + edgering_select(eed, select); + else if(G.qual & LR_ALTKEY) + edgeloop_select(eed, select); + } + else if(G.scene->selectmode & SCE_SELECT_VERTEX) { + if(G.qual == (LR_CTRLKEY | LR_ALTKEY) || G.qual == (LR_CTRLKEY | LR_ALTKEY |LR_SHIFTKEY)) + edgering_select(eed, select); + else if(G.qual & LR_ALTKEY) + edgeloop_select(eed, select); + } - /* frontbuffer draw of last selected only */ - unified_select_draw(NULL, eed, NULL); + /* frontbuffer draw of last selected only */ + unified_select_draw(NULL, eed, NULL); - EM_selectmode_flush(); - countall(); - allqueue(REDRAWVIEW3D, 0); - if (EM_texFaceCheck()) - allqueue(REDRAWIMAGE, 0); + EM_selectmode_flush(); + countall(); + allqueue(REDRAWVIEW3D, 0); + if (EM_texFaceCheck()) + allqueue(REDRAWIMAGE, 0); + } else { /*(G.scene->toolsettings->edge_mode == EDGE_MODE_TAG_*)*/ + int act = (edgetag_context_check(eed)==0); + int path = 0; + + if (G.qual == (LR_SHIFTKEY | LR_ALTKEY) && G.editMesh->selected.last) { + EditSelection *ese = G.editMesh->selected.last; + + if(ese && ese->type == EDITEDGE) { + EditEdge *eed_act; + eed_act = (EditEdge*)ese->data; + if (eed_act != eed) { + /* If shift is pressed we need to use the last active edge, (if it exists) */ + if (edgetag_shortest_path(eed_act, eed)) { + EM_remove_selection(eed_act, EDITEDGE); + EM_select_edge(eed_act, 0); + path = 1; + } + } + } + } + if (path==0) { + edgetag_context_set(eed, act); /* switch the edge option */ + } + + if (act) { + if ((eed->f & SELECT)==0) { + EM_select_edge(eed, 1); + EM_selectmode_flush(); + countall(); + } + /* even if this is selected it may not be in the selection list */ + EM_store_selection(eed, EDITEDGE); + } else { + if (eed->f & SELECT) { + EM_select_edge(eed, 0); + /* logic is differnt from above here since if this was selected we dont know if its in the selection list or not */ + EM_remove_selection(eed, EDITEDGE); + + EM_selectmode_flush(); + countall(); + } + } + + switch (G.scene->toolsettings->edge_mode) { + case EDGE_MODE_TAG_SEAM: + G.f |= G_DRAWSEAMS; + break; + case EDGE_MODE_TAG_SHARP: + G.f |= G_DRAWSHARP; + break; + case EDGE_MODE_TAG_CREASE: + G.f |= G_DRAWCREASES; + break; + case EDGE_MODE_TAG_BEVEL: + G.f |= G_DRAWBWEIGHTS; + break; + } + + unified_select_draw(NULL, eed, NULL); + + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); + allqueue(REDRAWVIEW3D, 0); + } + } } |