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:
2005-07-13 15:20:40 +00:00
parent 6a648da13f
commit 798d39dd4c
12 changed files with 2710 additions and 2224 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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[]= {