Well here it is. Subdivision/Loop Tools Recode Commit #1
Ton has been pushing me to get this in and finish it up with help, so here is a run down of the commit Revised Features Subdivide now is Edge based, allows for multicut Loopcut was recoded, now has multi option Knife tool now has multi option New Features Edgeslide Edgering select Removed Features Alt-B Edgeloop selection (use alt-RMB in edgemode) Shift-R Faceloop selection (use alt-RMB in facemode) Old Subdivide (Except for smooth which is left in until new one works) Todo Subdivide Smooth Math is broken - could use some help here (look for alter_co in editmesh_tools.c) Tweak mouse control of Edgeslide is hackish ATM Add Non-proportional movement to edgeslide Add smooth option to new loopcut I probably left something out. See here for more info http://wiki.blender.org/bin/view.pl/Blenderdev/EdgeSubdivision
This commit is contained in:
@@ -52,6 +52,7 @@ int BLI_linklist_length (struct LinkNode *list);
|
||||
void BLI_linklist_reverse (struct LinkNode **listp);
|
||||
|
||||
void BLI_linklist_prepend (struct LinkNode **listp, void *ptr);
|
||||
void BLI_linklist_append (struct LinkNode **listp, void *ptr);
|
||||
void BLI_linklist_prepend_arena (struct LinkNode **listp, void *ptr, struct MemArena *ma);
|
||||
|
||||
void BLI_linklist_free (struct LinkNode *list, LinkNodeFreeFP freefunc);
|
||||
|
||||
@@ -76,6 +76,23 @@ void BLI_linklist_prepend(LinkNode **listp, void *ptr) {
|
||||
*listp= nlink;
|
||||
}
|
||||
|
||||
void BLI_linklist_append(LinkNode **listp, void *ptr) {
|
||||
LinkNode *nlink= MEM_mallocN(sizeof(*nlink), "nlink");
|
||||
LinkNode *node = *listp;
|
||||
|
||||
nlink->link = ptr;
|
||||
nlink->next = NULL;
|
||||
|
||||
if(node == NULL){
|
||||
*listp = nlink;
|
||||
} else {
|
||||
while(node->next != NULL){
|
||||
node = node->next;
|
||||
}
|
||||
node->next = nlink;
|
||||
}
|
||||
}
|
||||
|
||||
void BLI_linklist_prepend_arena(LinkNode **listp, void *ptr, MemArena *ma) {
|
||||
LinkNode *nlink= BLI_memarena_alloc(ma, sizeof(*nlink));
|
||||
nlink->link= ptr;
|
||||
|
||||
@@ -101,6 +101,7 @@ extern void EM_free_backbuf_border(void);
|
||||
|
||||
extern void EM_selectmode_menu(void);
|
||||
|
||||
|
||||
extern void vertexnoise(void);
|
||||
extern void vertexsmooth(void);
|
||||
extern void righthandfaces(int select);
|
||||
@@ -135,20 +136,22 @@ extern void editmesh_deselect_by_material(int index);
|
||||
extern void Edge_Menu(void);
|
||||
extern void editmesh_mark_seam(int clear);
|
||||
|
||||
|
||||
/* ******************* editmesh_loop.c */
|
||||
|
||||
#define KNIFE_PROMPT 0
|
||||
#define KNIFE_EXACT 1
|
||||
#define KNIFE_MIDPOINT 2
|
||||
#define KNIFE_MULTICUT 3
|
||||
|
||||
extern void CutEdgeloop(int numcuts);
|
||||
extern void KnifeSubdivide(char mode);
|
||||
extern void LoopMenu(void);
|
||||
|
||||
#define LOOP_SELECT 1
|
||||
#define LOOP_CUT 2
|
||||
|
||||
extern void loopoperations(char mode);
|
||||
extern void vertex_loop_select(void);
|
||||
extern short sharesFace(struct EditEdge* e1, struct EditEdge* e2);
|
||||
|
||||
/* ******************* editmesh_tools.c */
|
||||
extern void convert_to_triface(int all);
|
||||
@@ -156,6 +159,7 @@ extern int removedoublesflag(short flag, float limit);
|
||||
extern void xsortvert_flag(int flag);
|
||||
extern void hashvert_flag(int flag);
|
||||
extern void subdivideflag(int flag, float rad, int beauty);
|
||||
extern void esubdivideflag(int flag, float rad, int beauty, int numcuts, int selecttype);
|
||||
extern void extrude_mesh(void);
|
||||
extern void split_mesh(void);
|
||||
extern void extrude_repeat_mesh(int steps, float offs);
|
||||
@@ -168,6 +172,7 @@ extern void edge_flip(void);
|
||||
extern void fill_mesh(void);
|
||||
extern void bevel_menu();
|
||||
void edge_rotate_selected(int dir);
|
||||
void EdgeSlide(short immediate, float imperc);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2048,7 +2048,7 @@ void do_meshbuts(unsigned short event)
|
||||
break;
|
||||
case B_SUBDIV:
|
||||
waitcursor(1);
|
||||
subdivideflag(1, 0.0, editbutflag & B_BEAUTY);
|
||||
esubdivideflag(1, 0.0, editbutflag & B_BEAUTY,1,0);
|
||||
countall();
|
||||
waitcursor(0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
@@ -2059,7 +2059,7 @@ void do_meshbuts(unsigned short event)
|
||||
if(button(&randfac, 1, 100, "Rand fac:")==0) return;
|
||||
waitcursor(1);
|
||||
fac= -( (float)randfac )/100;
|
||||
subdivideflag(1, fac, editbutflag & B_BEAUTY);
|
||||
esubdivideflag(1, fac, editbutflag & B_BEAUTY,1,0);
|
||||
countall();
|
||||
waitcursor(0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
|
||||
@@ -776,6 +776,7 @@ void add_primitiveMesh(int type)
|
||||
}
|
||||
else if(type==12) { /* Icosphere */
|
||||
EditVert *eva[12];
|
||||
EditEdge *eed;
|
||||
|
||||
/* clear all flags */
|
||||
eve= em->verts.first;
|
||||
@@ -792,14 +793,18 @@ void add_primitiveMesh(int type)
|
||||
eva[a]->f= 1+2;
|
||||
}
|
||||
for(a=0;a<20;a++) {
|
||||
EditFace *evtemp;
|
||||
v1= eva[ icoface[a][0] ];
|
||||
v2= eva[ icoface[a][1] ];
|
||||
v3= eva[ icoface[a][2] ];
|
||||
addfacelist(v1, v2, v3, 0, NULL, NULL);
|
||||
evtemp = addfacelist(v1, v2, v3, 0, NULL, NULL);
|
||||
evtemp->e1->f = 1+2;
|
||||
evtemp->e2->f = 1+2;
|
||||
evtemp->e3->f = 1+2;
|
||||
}
|
||||
|
||||
dia*=200;
|
||||
for(a=1; a<subdiv; a++) subdivideflag(2, dia, 0);
|
||||
for(a=1; a<subdiv; a++) esubdivideflag(2, dia, 0,1,0);
|
||||
/* and now do imat */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
@@ -809,6 +814,15 @@ void add_primitiveMesh(int type)
|
||||
}
|
||||
eve= eve->next;
|
||||
}
|
||||
|
||||
// Clear the flag 2 from the edges
|
||||
for(eed=em->edges.first;eed;eed=eed->next){
|
||||
if(eed->f & 2){
|
||||
eed->f &= !2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else if (type==13) { /* Monkey */
|
||||
extern int monkeyo, monkeynv, monkeynf;
|
||||
extern signed char monkeyf[][4];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -974,6 +974,74 @@ static void edgeloop_select(EditEdge *starteed, int select)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Almostly exactly the same code as faceloop select
|
||||
*/
|
||||
static void edgering_select(EditEdge *startedge, int select){
|
||||
EditMesh *em = G.editMesh;
|
||||
EditEdge *eed;
|
||||
EditFace *efa;
|
||||
int looking= 1;
|
||||
|
||||
/* in eed->f1 we put the valence (amount of faces in edge) */
|
||||
/* in eed->f2 we put tagged flag as correct loop */
|
||||
/* in efa->f1 we put tagged flag as correct to select */
|
||||
|
||||
for(eed= em->edges.first; eed; eed= eed->next) {
|
||||
eed->f1= 0;
|
||||
eed->f2= 0;
|
||||
}
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
efa->f1= 0;
|
||||
if(efa->h==0) {
|
||||
efa->e1->f1++;
|
||||
efa->e2->f1++;
|
||||
efa->e3->f1++;
|
||||
if(efa->e4) efa->e4->f1++;
|
||||
}
|
||||
}
|
||||
|
||||
// tag startedge OK
|
||||
startedge->f2= 1;
|
||||
|
||||
while(looking) {
|
||||
looking= 0;
|
||||
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
if(efa->e4 && efa->f1==0) { // not done quad
|
||||
if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { // valence ok
|
||||
|
||||
// if edge tagged, select opposing edge and mark face ok
|
||||
if(efa->e1->f2) {
|
||||
efa->e3->f2= 1;
|
||||
efa->f1= 1;
|
||||
looking= 1;
|
||||
}
|
||||
else if(efa->e2->f2) {
|
||||
efa->e4->f2= 1;
|
||||
efa->f1= 1;
|
||||
looking= 1;
|
||||
}
|
||||
if(efa->e3->f2) {
|
||||
efa->e1->f2= 1;
|
||||
efa->f1= 1;
|
||||
looking= 1;
|
||||
}
|
||||
if(efa->e4->f2) {
|
||||
efa->e2->f2= 1;
|
||||
efa->f1= 1;
|
||||
looking= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (de)select the edges */
|
||||
for(eed= em->edges.first; eed; eed= eed->next) {
|
||||
if(eed->f2) EM_select_edge(eed, select);
|
||||
}
|
||||
}
|
||||
/* ***************** MAIN MOUSE SELECTION ************** */
|
||||
|
||||
// just to have the functions nice together
|
||||
@@ -993,7 +1061,13 @@ static void mouse_mesh_loop(void)
|
||||
if(G.scene->selectmode & SCE_SELECT_FACE) {
|
||||
faceloop_select(eed, eed->f & SELECT);
|
||||
}
|
||||
else {
|
||||
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, eed->f & SELECT);
|
||||
else if(G.qual & LR_ALTKEY)
|
||||
edgeloop_select(eed, eed->f & SELECT);
|
||||
}
|
||||
else if(G.scene->selectmode & SCE_SELECT_VERTEX) {
|
||||
edgeloop_select(eed, eed->f & SELECT);
|
||||
}
|
||||
|
||||
@@ -1696,7 +1770,7 @@ void editmesh_mark_seam(int clear)
|
||||
void Edge_Menu() {
|
||||
short ret;
|
||||
|
||||
ret= pupmenu("Edge Specials%t|Mark Seam %x1|Clear Seam %x2|Rotate Edge CW%x3|Rotate Edge CCW%x4");
|
||||
ret= pupmenu("Edge Specials%t|Mark Seam %x1|Clear Seam %x2|Rotate Edge CW%x3|Rotate Edge CCW%x4|Loopcut%x6|Edge Slide%x5");
|
||||
|
||||
switch(ret)
|
||||
{
|
||||
@@ -1712,6 +1786,14 @@ void Edge_Menu() {
|
||||
case 4:
|
||||
edge_rotate_selected(1);
|
||||
break;
|
||||
case 5:
|
||||
EdgeSlide(0,0.0);
|
||||
BIF_undo_push("EdgeSlide");
|
||||
break;
|
||||
case 6:
|
||||
CutEdgeloop(1);
|
||||
BIF_undo_push("Loopcut New");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1897,7 +1897,7 @@ void special_editmenu(void)
|
||||
extern float doublimit;
|
||||
float fac;
|
||||
int nr,ret;
|
||||
short randfac;
|
||||
short randfac,numcuts;
|
||||
|
||||
if(G.obpose) {
|
||||
pose_special_editmenu();
|
||||
@@ -2025,25 +2025,37 @@ void special_editmenu(void)
|
||||
}
|
||||
else if(G.obedit->type==OB_MESH) {
|
||||
|
||||
nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Fractal%x2|Subdivide Smooth%x3|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11");
|
||||
if(nr>0) waitcursor(1);
|
||||
nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Multi Smooth - WIP%x12|Subdivide Smooth Old%x13|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11");
|
||||
//if(nr>0) waitcursor(1);
|
||||
|
||||
switch(nr) {
|
||||
case 1:
|
||||
subdivideflag(1, 0.0, editbutflag);
|
||||
BIF_undo_push("Subdivide");
|
||||
numcuts = 1;
|
||||
waitcursor(1);
|
||||
esubdivideflag(1, 0.0, editbutflag,numcuts,0);
|
||||
|
||||
BIF_undo_push("ESubdivide Single");
|
||||
//subdivideflag(1, 0.0, editbutflag);
|
||||
//BIF_undo_push("Subdivide");
|
||||
break;
|
||||
case 2:
|
||||
numcuts = 2;
|
||||
if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
|
||||
waitcursor(1);
|
||||
esubdivideflag(1, 0.0, editbutflag,numcuts,0);
|
||||
BIF_undo_push("ESubdivide");
|
||||
break;
|
||||
case 3:
|
||||
numcuts = 2;
|
||||
if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
|
||||
waitcursor(1);
|
||||
randfac= 10;
|
||||
if(button(&randfac, 1, 100, "Rand fac:")==0) return;
|
||||
fac= -( (float)randfac )/100;
|
||||
subdivideflag(1, fac, editbutflag);
|
||||
esubdivideflag(1, fac, editbutflag,numcuts,0);
|
||||
BIF_undo_push("Subdivide Fractal");
|
||||
break;
|
||||
case 3:
|
||||
subdivideflag(1, 0.0, editbutflag | B_SMOOTH);
|
||||
BIF_undo_push("Subdivide Smooth");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
mergemenu();
|
||||
break;
|
||||
@@ -2070,6 +2082,18 @@ void special_editmenu(void)
|
||||
case 11:
|
||||
bevel_menu();
|
||||
break;
|
||||
case 12:
|
||||
numcuts = 2;
|
||||
if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
|
||||
waitcursor(1);
|
||||
esubdivideflag(1, 0.0, editbutflag | B_SMOOTH,numcuts,0);
|
||||
BIF_undo_push("Subdivide Smooth");
|
||||
break;
|
||||
case 13:
|
||||
waitcursor(1);
|
||||
subdivideflag(1, 0.0, editbutflag | B_SMOOTH);
|
||||
BIF_undo_push("Subdivide Smooth");
|
||||
break;
|
||||
}
|
||||
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
|
||||
@@ -819,9 +819,6 @@ void do_view3d_select_meshmenu(void *arg, int event)
|
||||
case 5: /* select random */
|
||||
selectrandom_mesh();
|
||||
break;
|
||||
case 6: /* select Faceloop */
|
||||
loopoperations(LOOP_SELECT);
|
||||
break;
|
||||
case 7: /* select more */
|
||||
select_more();
|
||||
break;
|
||||
@@ -831,9 +828,6 @@ void do_view3d_select_meshmenu(void *arg, int event)
|
||||
case 9: /* select less */
|
||||
select_non_manifold();
|
||||
break;
|
||||
case 10: /* select vertexloop */
|
||||
vertex_loop_select();
|
||||
break;
|
||||
}
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
@@ -873,8 +867,6 @@ static uiBlock *view3d_select_meshmenu(void *arg_unused)
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
|
||||
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Face Loop...|Shift R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Vertex Loop|Alt B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Linked Vertices|Ctrl L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
|
||||
|
||||
if(curarea->headertype==HEADERTOP) {
|
||||
@@ -2088,25 +2080,25 @@ void do_view3d_edit_mesh_edgesmenu(void *arg, int event)
|
||||
switch(event) {
|
||||
|
||||
case 0: /* subdivide smooth */
|
||||
subdivideflag(1, 0.0, editbutflag | B_SMOOTH);
|
||||
esubdivideflag(1, 0.0, editbutflag | B_SMOOTH,1,0);
|
||||
BIF_undo_push("Subdivide Smooth");
|
||||
break;
|
||||
case 1: /*subdivide fractal */
|
||||
randfac= 10;
|
||||
if(button(&randfac, 1, 100, "Rand fac:")==0) return;
|
||||
fac= -( (float)randfac )/100;
|
||||
subdivideflag(1, fac, editbutflag);
|
||||
esubdivideflag(1, fac, editbutflag,1,0);
|
||||
BIF_undo_push("Subdivide Fractal");
|
||||
break;
|
||||
case 2: /* subdivide */
|
||||
subdivideflag(1, 0.0, editbutflag);
|
||||
esubdivideflag(1, 0.0, editbutflag,1,0);
|
||||
BIF_undo_push("Subdivide");
|
||||
break;
|
||||
case 3: /* knife subdivide */
|
||||
KnifeSubdivide(KNIFE_PROMPT);
|
||||
break;
|
||||
case 4: /* Loop subdivide */
|
||||
loopoperations(LOOP_CUT);
|
||||
CutEdgeloop(1);
|
||||
break;
|
||||
case 5: /* Make Edge/Face */
|
||||
addedgeface_mesh();
|
||||
@@ -2130,6 +2122,9 @@ void do_view3d_edit_mesh_edgesmenu(void *arg, int event)
|
||||
case 11: /* Rotate Edge */
|
||||
edge_rotate_selected(1);
|
||||
break;
|
||||
case 12: /* Edgeslide */
|
||||
EdgeSlide(0,0.0);
|
||||
break;
|
||||
}
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
@@ -2170,7 +2165,10 @@ static uiBlock *view3d_edit_mesh_edgesmenu(void *arg_unused)
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rotate Edge CW|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rotate Edge CCW|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rotate Edge CCW|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Edgeslide |Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
|
||||
|
||||
|
||||
uiBlockSetDirection(block, UI_RIGHT);
|
||||
uiTextBoundsBlock(block, 60);
|
||||
|
||||
@@ -1132,14 +1132,6 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
case BKEY:
|
||||
if((G.qual==LR_SHIFTKEY))
|
||||
set_render_border();
|
||||
else if((G.qual==LR_ALTKEY)){
|
||||
if(G.obedit && G.obedit->type==OB_MESH) {
|
||||
/* Loop Select Operations */
|
||||
/* Vertexloop */
|
||||
/* Faceloop */
|
||||
vertex_loop_select();
|
||||
}
|
||||
}
|
||||
else if((G.qual==0))
|
||||
borderselect();
|
||||
break;
|
||||
@@ -1535,12 +1527,11 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
if((G.qual==LR_SHIFTKEY)) {
|
||||
if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
|
||||
selectrow_nurb();
|
||||
else if (G.obedit->type==OB_MESH)
|
||||
loopoperations(LOOP_SELECT);
|
||||
}
|
||||
else if(G.qual==LR_CTRLKEY) {
|
||||
if (G.obedit->type==OB_MESH)
|
||||
loopoperations(LOOP_CUT);
|
||||
CutEdgeloop(1);
|
||||
BIF_undo_push("Cut Edgeloop");
|
||||
}
|
||||
else if((G.qual==0)) {
|
||||
initTransform(TFM_ROTATION, CTX_NONE);
|
||||
|
||||
@@ -1735,7 +1735,10 @@ static TBitem tb_mesh_edit_edge[]= {
|
||||
{ 0, "SEPR", 0, NULL},
|
||||
{ 0, "Crease SubSurf|Shift E", 9, NULL},
|
||||
{ 0, "SEPR", 0, NULL},
|
||||
{ 0, "Rotate Edge|Ctrl E", 10, NULL},
|
||||
{ 0, "Rotate Edge CW|Ctrl E", 10, NULL},
|
||||
{ 0, "Rotate Edge CCW|Ctrl E", 11, NULL},
|
||||
{ 0, "SEPR", 0, NULL},
|
||||
{ 0, "Edgeslide|Ctrl E", 12, NULL},
|
||||
{ -1, "", 0, do_view3d_edit_mesh_edgesmenu}};
|
||||
|
||||
static TBitem tb_mesh_edit_face[]= {
|
||||
|
||||
Reference in New Issue
Block a user