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
path: root/source
diff options
context:
space:
mode:
authorAlexander Ewering <blender@instinctive.de>2003-10-13 03:43:26 +0400
committerAlexander Ewering <blender@instinctive.de>2003-10-13 03:43:26 +0400
commit5c2005cf06d786985ebf2213aa25070bdbda2a4f (patch)
tree7e14efbe3813412840c70452a2b88d5264027176 /source
parent1bc0f43da04e856586cb674cec5bacc98ca26f8a (diff)
Robert (DetectiveThorn) Wenzlaff's Knife subdivide tool. See previous
message on Bf-committers for description.
Diffstat (limited to 'source')
-rw-r--r--source/blender/include/BIF_editmesh.h11
-rw-r--r--source/blender/include/BIF_graphics.h3
-rw-r--r--source/blender/include/BSE_view.h1
-rw-r--r--source/blender/src/editmesh.c537
-rw-r--r--source/blender/src/ghostwinlay.c3
-rw-r--r--source/blender/src/space.c5
-rw-r--r--source/blender/src/view.c16
7 files changed, 485 insertions, 91 deletions
diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h
index 3e545ac4507..2820bbee242 100644
--- a/source/blender/include/BIF_editmesh.h
+++ b/source/blender/include/BIF_editmesh.h
@@ -48,6 +48,17 @@ void vertexsmooth(void);
void make_sticky(void);
void deselectall_mesh(void);
+/* For Knife subdivide */
+typedef struct CutCurve {
+ short x;
+ short y;
+} CutCurve;
+
+void KnifeSubdivide(void);
+CutCurve *get_mouse_trail(int * length);
+short seg_intersect(struct EditEdge * e, CutCurve *c, int len);
+/* End Knife Subdiv */
+
/** Aligns the selected TFace's of @a me to the @a v3d,
* using the given axis (0-2). Can give a user error.
*/
diff --git a/source/blender/include/BIF_graphics.h b/source/blender/include/BIF_graphics.h
index 90e77e1fb7e..05e0883e81d 100644
--- a/source/blender/include/BIF_graphics.h
+++ b/source/blender/include/BIF_graphics.h
@@ -47,7 +47,8 @@ enum {
CURSOR_Y_MOVE,
CURSOR_HELP,
CURSOR_STD,
- CURSOR_NONE
+ CURSOR_NONE,
+ CURSOR_PENCIL
};
void set_cursor(int curs);
diff --git a/source/blender/include/BSE_view.h b/source/blender/include/BSE_view.h
index e6477012c8a..f46de2ba3ff 100644
--- a/source/blender/include/BSE_view.h
+++ b/source/blender/include/BSE_view.h
@@ -46,6 +46,7 @@ void initgrabz(float x, float y, float z);
void window_to_3d(float *vec, short mx, short my);
void project_short(float *vec, short *adr);
void project_short_noclip(float *vec, short *adr);
+void project_float(float *vec, float *adr);
int boundbox_clip(float obmat[][4], struct BoundBox *bb);
void fdrawline(float x1, float y1, float x2, float y2);
void fdrawbox(float x1, float y1, float x2, float y2);
diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c
index 81024270d63..4da75e11183 100644
--- a/source/blender/src/editmesh.c
+++ b/source/blender/src/editmesh.c
@@ -2833,19 +2833,22 @@ void hashvert_flag(int flag)
MEM_freeN(sortblock);
}
-static unsigned int cpack_half(unsigned int col1, unsigned int col2)
+static unsigned int cpack_fact(unsigned int col1, unsigned int col2, float fact)
{
char *cp1, *cp2, *cp;
unsigned int col=0;
+ float fact1;
+ fact1=1-fact; /*result is fact% col1 and (1-fact) % col2 */
+
cp1= (char *)&col1;
cp2= (char *)&col2;
cp= (char *)&col;
- cp[0]= (cp1[0]+cp2[0])>>1;
- cp[1]= (cp1[1]+cp2[1])>>1;
- cp[2]= (cp1[2]+cp2[2])>>1;
- cp[3]= (cp1[3]+cp2[3])>>1;
+ cp[0]= fact*cp1[0]+fact1*cp2[0];
+ cp[1]= fact*cp1[1]+fact1*cp2[1];
+ cp[2]= fact*cp1[2]+fact1*cp2[2];
+ cp[3]= fact*cp1[3]+fact1*cp2[3];
return col;
}
@@ -2870,14 +2873,15 @@ static void set_wuv(int tot, EditVlak *evl, int v1, int v2, int v3, int v4)
float *uv, uvo[4][2];
unsigned int *col, colo[4], col1, col2;
int a, v;
-
- memcpy(uvo, evl->uv, sizeof(uvo));
- uv= evl->uv[0];
-
- memcpy(colo, evl->col, sizeof(colo));
- col= evl->col;
-
- if(tot==4) {
+ /* Numbers corespond to verts (corner points), */
+ /* edge->vn's (center edges), the Center */
+ memcpy(uvo, evl->uv, sizeof(uvo)); /* And the quincunx points of a face */
+ uv= evl->uv[0]; /* as shown here: */
+ /* 2 5 1 */
+ memcpy(colo, evl->col, sizeof(colo)); /* 10 13 */
+ col= evl->col; /* 6 9 8 */
+ /* 11 12 */
+ if(tot==4) { /* 3 7 4 */
for(a=0; a<4; a++, uv+=2, col++) {
if(a==0) v= v1;
else if(a==1) v= v2;
@@ -2893,17 +2897,48 @@ static void set_wuv(int tot, EditVlak *evl, int v1, int v2, int v3, int v4)
}
else if(v==8) {
uv_half(uv, uvo[3], uvo[0]);
- *col= cpack_half(colo[3], colo[0]);
+ *col= cpack_fact(colo[3], colo[0], 0.5);
}
else if(v==9) {
uv_quart(uv, uvo[0]);
- col1= cpack_half(colo[1], colo[0]);
- col2= cpack_half(colo[2], colo[3]);
- *col= cpack_half(col1, col2);
+ col1= cpack_fact(colo[1], colo[0], 0.5);
+ col2= cpack_fact(colo[2], colo[3], 0.5);
+ *col= cpack_fact(col1, col2, 0.5);
}
- else {
+ /* Cases for adjacent edge square subdivide Real voodoo */
+ /* 1/2 closest corner + 1/4 adjacent corners */
+ else if (v==10){ /* case test==3 in subdivideflag() */
+ uv[0]=(2*uvo[1][0]+uvo[0][0]+uvo[2][0])/4;
+ uv[1]=(2*uvo[1][1]+uvo[0][1]+uvo[2][1])/4;
+ col1= cpack_fact(colo[1], colo[0], 0.75);
+ col2= cpack_fact(colo[2], colo[3], 0.75);
+ *col= cpack_fact(col1, col2, 0.75);
+ }
+ else if (v==11) { /* case of test==6 */
+ uv[0]=(2*uvo[2][0]+uvo[1][0]+uvo[3][0])/4;
+ uv[1]=(2*uvo[2][1]+uvo[1][1]+uvo[3][1])/4;
+ col1= cpack_fact(colo[1], colo[0], 0.75);
+ col2= cpack_fact(colo[2], colo[3], 0.75);
+ *col= cpack_fact(col1, col2, 0.25);
+ }
+ else if (v==12) { /* case of test==12 */
+ uv[0]=(2*uvo[3][0]+uvo[2][0]+uvo[0][0])/4;
+ uv[1]=(2*uvo[3][1]+uvo[2][1]+uvo[0][1])/4;
+ col1= cpack_fact(colo[1], colo[0], 0.25);
+ col2= cpack_fact(colo[2], colo[3], 0.25);
+ *col= cpack_fact(col1, col2, 0.25);
+ }
+ else if (v==13) { /* case of test==9 */
+ uv[0]=(2*uvo[0][0]+uvo[1][0]+uvo[3][0])/4;
+ uv[1]=(2*uvo[0][1]+uvo[1][1]+uvo[3][1])/4;
+ col1= cpack_fact(colo[1], colo[0], 0.25);
+ col2= cpack_fact(colo[2], colo[3], 0.25);
+ *col= cpack_fact(col1, col2, 0.75);
+ }
+ /* default for consecutive verts*/
+ else {
uv_half(uv, uvo[v-5], uvo[v-4]);
- *col= cpack_half(colo[v-5], colo[v-4]);
+ *col= cpack_fact(colo[v-5], colo[v-4], 0.5);
}
}
}
@@ -2920,11 +2955,11 @@ static void set_wuv(int tot, EditVlak *evl, int v1, int v2, int v3, int v4)
}
else if(v==7) {
uv_half(uv, uvo[2], uvo[0]);
- *col= cpack_half(colo[2], colo[0]);
+ *col= cpack_fact(colo[2], colo[0], 0.5);
}
else {
uv_half(uv, uvo[v-5], uvo[v-4]);
- *col= cpack_half(colo[v-5], colo[v-4]);
+ *col= cpack_fact(colo[v-5], colo[v-4], 0.5);
}
}
}
@@ -2961,20 +2996,19 @@ static void addvlak_subdiv(EditVlak *evl, int val1, int val2, int val3, int val4
EditVlak *w;
EditVert *v1, *v2, *v3, *v4;
- if(val1==9) v1= eve;
+ if(val1>=9) v1= eve;
else v1= vert_from_number(evl, val1);
- if(val2==9) v2= eve;
+ if(val2>=9) v2= eve;
else v2= vert_from_number(evl, val2);
- if(val3==9) v3= eve;
+ if(val3>=9) v3= eve;
else v3= vert_from_number(evl, val3);
- if(val4==9) v4= eve;
+ if(val4>=9) v4= eve;
else v4= vert_from_number(evl, val4);
w= addvlaklist(v1, v2, v3, v4, evl);
-
if(w) {
if(evl->v4) set_wuv(4, w, val1, val2, val3, val4);
else set_wuv(3, w, val1, val2, val3, val4);
@@ -3050,7 +3084,7 @@ void subdivideflag(int flag, float rad, int beauty)
EditVert *eve;
EditEdge *eed, *e1, *e2, *e3, *e4, *nexted;
EditVlak *evl;
- float fac, vec[3], vec1[3], len1, len2, len3;
+ float fac, vec[3], vec1[3], len1, len2, len3, percent;
short test;
if(beauty & B_SMOOTH) {
@@ -3063,11 +3097,9 @@ void subdivideflag(int flag, float rad, int beauty)
/* edgeflags */
eed= G.eded.first;
- while(eed) {
-
+ while((eed) && !(beauty & B_KNIFE)) {
if( (eed->v1->f & flag) && (eed->v2->f & flag) ) eed->f= flag;
- else eed->f= 0;
-
+ else eed->f= 0;
eed= eed->next;
}
@@ -3101,7 +3133,6 @@ void subdivideflag(int flag, float rad, int beauty)
}
}
else {
-
/* area */
len1= AreaT3Dfl(evl->v1->co, evl->v2->co, evl->v3->co);
if(len1 <= doublimit) {
@@ -3110,7 +3141,6 @@ void subdivideflag(int flag, float rad, int beauty)
evl->e3->f = 0;
}
else {
-
len1= VecLenf(evl->v1->co, evl->v2->co) ;
len2= VecLenf(evl->v2->co, evl->v3->co) ;
len3= VecLenf(evl->v3->co, evl->v1->co) ;
@@ -3141,10 +3171,13 @@ void subdivideflag(int flag, float rad, int beauty)
eed= G.eded.first;
while(eed) {
if(eed->f & flag) {
+
+ if (beauty & B_PERCENTSUBD) percent=(float)(eed->f1)/32768.0;
+ else percent=0.5;
- vec[0]= (eed->v1->co[0]+eed->v2->co[0])/2.0;
- vec[1]= (eed->v1->co[1]+eed->v2->co[1])/2.0;
- vec[2]= (eed->v1->co[2]+eed->v2->co[2])/2.0;
+ vec[0]= (1-percent)*eed->v1->co[0] + percent*eed->v2->co[0];
+ vec[1]= (1-percent)*eed->v1->co[1] + percent*eed->v2->co[1];
+ vec[2]= (1-percent)*eed->v1->co[2] + percent*eed->v2->co[2];
if(rad > 0.0) { /* subdivide sphere */
Normalise(vec);
@@ -3203,9 +3236,8 @@ void subdivideflag(int flag, float rad, int beauty)
test+= 8;
e4->f= 1;
}
-
if(test) {
- if(evl->v4==0) {
+ if(evl->v4==0) { /* All the permutations of 3 edges*/
if((test & 3)==3) addvlak_subdiv(evl, 2, 2+4, 1+4, 0, 0);
if((test & 6)==6) addvlak_subdiv(evl, 3, 3+4, 2+4, 0, 0);
if((test & 5)==5) addvlak_subdiv(evl, 1, 1+4, 3+4, 0, 0);
@@ -3251,9 +3283,9 @@ void subdivideflag(int flag, float rad, int beauty)
evl->e3= addedgelist(evl->v3, evl->v1);
}
- else {
+ else { /* All the permutations of 4 faces */
if(test==15) {
- /* add a new point */
+ /* add a new point in center */
CalcCent4f(vec, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co);
if(beauty & B_SMOOTH) {
@@ -3262,7 +3294,7 @@ void subdivideflag(int flag, float rad, int beauty)
eve= addvertlist(vec);
eve->f |= flag;
-
+
addvlak_subdiv(evl, 2, 2+4, 9, 1+4, eve);
addvlak_subdiv(evl, 3, 3+4, 9, 2+4, eve);
addvlak_subdiv(evl, 4, 4+4, 9, 3+4, eve);
@@ -3272,13 +3304,13 @@ void subdivideflag(int flag, float rad, int beauty)
evl->v4= e4->vn;
set_wuv(4, evl, 1, 1+4, 9, 4+4);
}
- else {
- if((test & 3)==3) addvlak_subdiv(evl, 1+4, 2, 2+4, 0, 0);
- if((test & 6)==6) addvlak_subdiv(evl, 2+4, 3, 3+4, 0, 0);
- if((test & 12)==12) addvlak_subdiv(evl, 3+4, 4, 4+4, 0, 0);
- if((test & 9)==9) addvlak_subdiv(evl, 4+4, 1, 1+4, 0, 0);
+ else {
+ if(((test & 3)==3)&&(test!=3)) addvlak_subdiv(evl, 1+4, 2, 2+4, 0, 0);
+ if(((test & 6)==6)&&(test!=6)) addvlak_subdiv(evl, 2+4, 3, 3+4, 0, 0);
+ if(((test & 12)==12)&&(test!=12)) addvlak_subdiv(evl, 3+4, 4, 4+4, 0, 0);
+ if(((test & 9)==9)&&(test!=9)) addvlak_subdiv(evl, 4+4, 1, 1+4, 0, 0);
- if(test==1) {
+ if(test==1) { /* Edge 1 has new vert */
addvlak_subdiv(evl, 1+4, 2, 3, 0, 0);
addvlak_subdiv(evl, 1+4, 3, 4, 0, 0);
evl->v2= e1->vn;
@@ -3286,14 +3318,14 @@ void subdivideflag(int flag, float rad, int beauty)
evl->v4= 0;
set_wuv(4, evl, 1, 1+4, 4, 0);
}
- else if(test==2) {
+ else if(test==2) { /* Edge 2 has new vert */
addvlak_subdiv(evl, 2+4, 3, 4, 0, 0);
addvlak_subdiv(evl, 2+4, 4, 1, 0, 0);
evl->v3= e2->vn;
evl->v4= 0;
set_wuv(4, evl, 1, 2, 2+4, 0);
}
- else if(test==4) {
+ else if(test==4) { /* Edge 3 has new vert */
addvlak_subdiv(evl, 3+4, 4, 1, 0, 0);
addvlak_subdiv(evl, 3+4, 1, 2, 0, 0);
evl->v1= evl->v2;
@@ -3302,7 +3334,7 @@ void subdivideflag(int flag, float rad, int beauty)
evl->v4= 0;
set_wuv(4, evl, 2, 3, 3+4, 0);
}
- else if(test==8) {
+ else if(test==8) { /* Edge 4 has new vert */
addvlak_subdiv(evl, 4+4, 1, 2, 0, 0);
addvlak_subdiv(evl, 4+4, 2, 3, 0, 0);
evl->v1= evl->v3;
@@ -3311,71 +3343,110 @@ void subdivideflag(int flag, float rad, int beauty)
evl->v4= 0;
set_wuv(4, evl, 3, 4, 4+4, 0);
}
- else if(test==3) {
- addvlak_subdiv(evl, 1+4, 2+4, 4, 0, 0);
- addvlak_subdiv(evl, 2+4, 3, 4, 0, 0);
- evl->v2= e1->vn;
- evl->v3= evl->v4;
- evl->v4= 0;
- set_wuv(4, evl, 1, 1+4, 4, 0);
+ else if(test==3) { /*edge 1&2 */
+ /* make new vert in center of new edge */
+ vec[0]=(e1->vn->co[0]+e2->vn->co[0])/2;
+ vec[1]=(e1->vn->co[1]+e2->vn->co[1])/2;
+ vec[2]=(e1->vn->co[2]+e2->vn->co[2])/2;
+ eve= addvertlist(vec);
+ eve->f |= flag;
+ /* Add new faces */
+ addvlak_subdiv(evl, 4, 10, 2+4, 3, eve);
+ addvlak_subdiv(evl, 4, 1, 1+4, 10, eve);
+ /* orig face becomes small corner */
+ evl->v1=e1->vn;
+ //evl->v2=evl->v2;
+ evl->v3=e2->vn;
+ evl->v4=eve;
+
+ set_wuv(4, evl, 1+4, 2, 2+4, 10);
}
- else if(test==6) {
- addvlak_subdiv(evl, 2+4, 3+4, 1, 0, 0);
- addvlak_subdiv(evl, 3+4, 4, 1, 0, 0);
- evl->v3= e2->vn;
- evl->v4= 0;
- set_wuv(4, evl, 1, 2, 2+4, 0);
+ else if(test==6) { /* 2&3 */
+ /* make new vert in center of new edge */
+ vec[0]=(e2->vn->co[0]+e3->vn->co[0])/2;
+ vec[1]=(e2->vn->co[1]+e3->vn->co[1])/2;
+ vec[2]=(e2->vn->co[2]+e3->vn->co[2])/2;
+ eve= addvertlist(vec);
+ eve->f |= flag;
+ /*New faces*/
+ addvlak_subdiv(evl, 1, 11, 3+4, 4, eve);
+ addvlak_subdiv(evl, 1, 2, 2+4, 11, eve);
+ /* orig face becomes small corner */
+ evl->v1=e2->vn;
+ evl->v2=evl->v3;
+ evl->v3=e3->vn;
+ evl->v4=eve;
+
+ set_wuv(4, evl, 2+4, 3, 3+4, 11);
}
- else if(test==12) {
- addvlak_subdiv(evl, 3+4, 4+4, 2, 0, 0);
- addvlak_subdiv(evl, 4+4, 1, 2, 0, 0);
- evl->v1= evl->v2;
- evl->v2= evl->v3;
- evl->v3= e3->vn;
- evl->v4= 0;
- set_wuv(4, evl, 2, 3, 3+4, 0);
+ else if(test==12) { /* 3&4 */
+ /* make new vert in center of new edge */
+ vec[0]=(e3->vn->co[0]+e4->vn->co[0])/2;
+ vec[1]=(e3->vn->co[1]+e4->vn->co[1])/2;
+ vec[2]=(e3->vn->co[2]+e4->vn->co[2])/2;
+ eve= addvertlist(vec);
+ eve->f |= flag;
+ /*New Faces*/
+ addvlak_subdiv(evl, 2, 12, 4+4, 1, eve);
+ addvlak_subdiv(evl, 2, 3, 3+4, 12, eve);
+ /* orig face becomes small corner */
+ evl->v1=e3->vn;
+ evl->v2=evl->v4;
+ evl->v3=e4->vn;
+ evl->v4=eve;
+
+ set_wuv(4, evl, 3+4, 4, 4+4, 12);
}
- else if(test==9) {
- addvlak_subdiv(evl, 4+4, 1+4, 3, 0, 0);
- addvlak_subdiv(evl, 1+4, 2, 3, 0, 0);
- evl->v1= evl->v3;
- evl->v2= evl->v4;
- evl->v3= e4->vn;
- evl->v4= 0;
- set_wuv(4, evl, 3, 4, 4+4, 0);
+ else if(test==9) { /* 4&1 */
+ /* make new vert in center of new edge */
+ vec[0]=(e1->vn->co[0]+e4->vn->co[0])/2;
+ vec[1]=(e1->vn->co[1]+e4->vn->co[1])/2;
+ vec[2]=(e1->vn->co[2]+e4->vn->co[2])/2;
+ eve= addvertlist(vec);
+ eve->f |= flag;
+ /*New Faces*/
+ addvlak_subdiv(evl, 3, 13, 1+4, 2, eve);
+ addvlak_subdiv(evl, 3, 4, 4+4, 13, eve);
+ /* orig face becomes small corner */
+ evl->v2=evl->v1;
+ evl->v1=e4->vn;
+ evl->v3=e1->vn;
+ evl->v4=eve;
+
+ set_wuv(4, evl, 4+4, 1, 1+4, 13);
}
- else if(test==5) {
+ else if(test==5) { /* 1&3 */
addvlak_subdiv(evl, 1+4, 2, 3, 3+4, 0);
evl->v2= e1->vn;
evl->v3= e3->vn;
set_wuv(4, evl, 1, 1+4, 3+4, 4);
}
- else if(test==10) {
+ else if(test==10) { /* 2&4 */
addvlak_subdiv(evl, 2+4, 3, 4, 4+4, 0);
evl->v3= e2->vn;
evl->v4= e4->vn;
set_wuv(4, evl, 1, 2, 2+4, 4+4);
- }
-
- else if(test==7) {
+ }/* Unfortunately, there is no way to avoid tris on 1 or 3 edges*/
+ else if(test==7) { /*1,2&3 */
addvlak_subdiv(evl, 1+4, 2+4, 3+4, 0, 0);
evl->v2= e1->vn;
evl->v3= e3->vn;
set_wuv(4, evl, 1, 1+4, 3+4, 4);
}
- else if(test==14) {
+
+ else if(test==14) { /* 2,3&4 */
addvlak_subdiv(evl, 2+4, 3+4, 4+4, 0, 0);
evl->v3= e2->vn;
evl->v4= e4->vn;
set_wuv(4, evl, 1, 2, 2+4, 4+4);
}
- else if(test==13) {
+ else if(test==13) {/* 1,3&4 */
addvlak_subdiv(evl, 3+4, 4+4, 1+4, 0, 0);
evl->v4= e3->vn;
evl->v1= e1->vn;
set_wuv(4, evl, 1+4, 3, 3, 3+4);
}
- else if(test==11) {
+ else if(test==11) { /* 1,2,&4 */
addvlak_subdiv(evl, 4+4, 1+4, 2+4, 0, 0);
evl->v1= e4->vn;
evl->v2= e2->vn;
@@ -3383,7 +3454,7 @@ void subdivideflag(int flag, float rad, int beauty)
}
}
evl->e1= addedgelist(evl->v1, evl->v2);
- evl->e2= addedgelist(evl->v2, evl->v3);
+ evl->e2= addedgelist(evl->v2, evl->v3);
if(evl->v4) evl->e3= addedgelist(evl->v3, evl->v4);
else evl->e3= addedgelist(evl->v3, evl->v1);
if(evl->v4) evl->e4= addedgelist(evl->v4, evl->v1);
@@ -6527,3 +6598,293 @@ void editmesh_align_view_to_selected(View3D *v3d, int axis)
view3d_align_axis_to_vector(v3d, axis, norm);
}
}
+
+/*
+
+Read a trail of mouse coords and return them as an array of CutCurve structs
+len returns number of mouse coords read before commiting with RETKEY
+It is up to the caller to free the block when done with it,
+
+this doesn't belong here.....
+ */
+
+CutCurve *get_mouse_trail(int *len){
+
+ CutCurve *curve,*temp;
+ short event, val, ldown=0, restart=0, rubberband=0;
+ short mval[2], lockaxis=0, lockx=0, locky=0, lastx=0, lasty=0;
+ int i=0, j, blocks=1, lasti=0;
+
+ *len=0;
+ curve=(CutCurve *)MEM_callocN(1024*sizeof(CutCurve), "MouseTrail");
+
+ if (!curve) {
+ printf("failed to allocate memory in get_mouse_trail()\n");
+ return(NULL);
+ }
+ mywinset(curarea->win);
+ glDrawBuffer(GL_FRONT);
+ persp(0);
+ event=extern_qread(&val);
+ while((event != RETKEY ) && (event != RIGHTMOUSE) ){
+ event=extern_qread(&val); /* Enter or RMB indicates finish */
+
+ if (event==ESCKEY){
+ for(j=1;j<i;j++) sdrawXORline(curve[j-1].x, curve[j-1].y, curve[j].x, curve[j].y );
+ if (curve) MEM_freeN(curve);
+ *len=0;
+ return(NULL);
+ break;
+ }
+
+ if (rubberband) { /* rubberband mode, undraw last rubberband */
+ sdrawXORline(curve[i-1].x, curve[i-1].y,mval[0], mval[1]);
+ glFlush();
+ rubberband=0;
+ }
+
+ getmouseco_areawin(mval);
+
+ if (lockaxis==1) mval[1]=locky;
+ if (lockaxis==2) mval[0]=lockx;
+
+ if ( ((i==0) || (mval[0]!=curve[i-1].x) || (mval[1]!=curve[i-1].y))
+ && (get_mbut() & L_MOUSE) ){ /* record changes only, if LMB down */
+
+ lastx=curve[i].x=mval[0];
+ lasty=curve[i].y=mval[1];
+
+ lockaxis=0;
+
+ i++;
+
+ ldown=1;
+ if (restart) {
+ for(j=1;j<i;j++) sdrawXORline(curve[j-1].x, curve[j-1].y, curve[j].x, curve[j].y);
+ if (rubberband) sdrawXORline(curve[j].x, curve[j].y, mval[0], mval[1]);
+ glFlush();
+ rubberband=0;
+ lasti=i=0;
+ restart=0;
+ ldown=0;
+ }
+ }
+
+ if ((event==MIDDLEMOUSE)&&(get_mbut()&M_MOUSE)&&(i)){/*MMB Down*/
+ /*determine which axis to lock to, or clear if locked */
+ if (lockaxis) lockaxis=0;
+ else if (abs(curve[i-1].x-mval[0]) > abs(curve[i-1].y-mval[1])) lockaxis=1;
+ else lockaxis=2;
+
+ if (lockaxis) {
+ lockx=lastx;
+ locky=lasty;
+ }
+ }
+
+ if ((i>1)&&(i!=lasti)) { /*Draw recorded part of curve */
+ sdrawXORline(curve[i-2].x, curve[i-2].y, curve[i-1].x, curve[i-1].y);
+ glFlush();
+ }
+
+ if ((i==lasti)&&(i>0)) { /*Draw rubberband */
+ sdrawXORline(curve[i-1].x, curve[i-1].y,mval[0], mval[1]);
+ glFlush();
+ rubberband=1;
+ }
+ lasti=i;
+
+ if (i>=blocks*1024) { /* reallocate data if out of room */
+ temp=curve;
+ curve=(CutCurve *)MEM_callocN((blocks+1)*1024*sizeof(CutCurve), "MouseTrail");
+ if (!curve) {
+ printf("failed to re-allocate memory in get_mouse_trail()\n");
+ return(NULL);
+ }
+ memcpy(curve, temp, blocks*1024*sizeof(CutCurve));
+ blocks++;
+ MEM_freeN(temp);
+ }
+ }
+ for(j=1;j<i;j++) {
+ sdrawXORline(curve[j-1].x, curve[j-1].y, curve[j].x, curve[j].y );
+ }
+ glFlush();
+ *len=i;
+ return(curve);
+}
+
+/* ******************************************************************** */
+/* Knife Subdivide Tool. Subdivides edges intersected by a mouse trail
+ drawn by user.
+
+ Currently mapped to KKey when in MeshEdit mode.
+ Usage:
+ Hit K,
+ Hold LMB down to draw path, hit RETKEY.
+ ESC cancels as expected.
+
+ Contributed by Robert Wenzlaff (Det. Thorn).
+*/
+
+void KnifeSubdivide(){
+
+ int oldcursor, len=0;
+ short isect=0, mode=0;
+ CutCurve *curve;
+ EditEdge *eed;
+
+ if (G.obedit==0) return;
+
+ /* Set a knife cursor here ??? */
+ oldcursor=get_cursor();
+ set_cursor(CURSOR_PENCIL);
+
+ calc_meshverts_ext(); /*Update screen coords for current window */
+
+ curve=get_mouse_trail(&len);
+
+ if (curve) mode=pupmenu("Cut Type %t|Intersect%x1|50%%x2|");
+
+ if (curve && len && mode){
+ eed= G.eded.first;
+ while(eed) {
+ if((eed->v1->f)&&(eed->v2->f)){
+ isect=seg_intersect(eed, curve, len);
+ if (isect) eed->f=1;
+ else eed->f=0;
+ eed->f1=isect;
+ //printf("isect=%i\n", isect);
+ }
+ else {
+ eed->f=0;
+ eed->f1=0;
+ }
+ eed= eed->next;
+ }
+
+ if (mode==1) subdivideflag(1, 0, B_KNIFE|B_PERCENTSUBD);
+ else if (mode==2) subdivideflag(1, 0, B_KNIFE);
+
+ addqueue(curarea->win, REDRAW, 1);
+
+ eed=G.eded.first;
+ while(eed){
+ eed->f=0;
+ eed->f1=0;
+ eed=eed->next;
+ }
+ }
+ /* Return ot old cursor and flags...*/
+ set_cursor(oldcursor);
+ if (curve) MEM_freeN(curve);
+}
+
+/* seg_intersect() Determines if and where a mouse trail intersects an EditEdge */
+
+short seg_intersect(EditEdge *e, CutCurve *c, int len){
+#define MAXSLOPE 100000
+ short isect=0;
+ float x11, y11, x12=0, y12=0, x2max, x2min, y2max;
+ float y2min, dist, lastdist=0, xdiff2, xdiff1;
+ float m1, b1, m2, b2, x21, x22, y21, y22, xi;
+ float yi, x1min, x1max, y1max, y1min, perc=0;
+ float scr[2], co[4];
+ int i;
+
+ /* Get screen coords of verts (v->xs and v->ys clip if off screen */
+ VECCOPY(co, e->v1->co);
+ co[3]= 1.0;
+ Mat4MulVec4fl(G.obedit->obmat, co);
+ project_float(co, scr);
+ x21=scr[0];
+ y21=scr[1];
+
+ VECCOPY(co, e->v2->co);
+ co[3]= 1.0;
+ Mat4MulVec4fl(G.obedit->obmat, co);
+ project_float(co, scr);
+ x22=scr[0];
+ y22=scr[1];
+
+ xdiff2=(x22-x21);
+ if (xdiff2) {
+ m2=(y22-y21)/xdiff2;
+ b2= ((x22*y21)-(x21*y22))/xdiff2;
+ }
+ else {
+ m2=MAXSLOPE; /* Verticle slope */
+ b2=x22;
+ }
+ for (i=0; i<len; i++){
+ if (i>0){
+ x11=x12;
+ y11=y12;
+ }
+ else {
+ x11=c[i].x;
+ y11=c[i].y;
+ }
+ x12=c[i].x;
+ y12=c[i].y;
+
+ /* Perp. Distance from point to line */
+ if (m2!=MAXSLOPE) dist=(y12-m2*x12-b2);/* /sqrt(m2*m2+1); Only looking for */
+ /* change in sign. Skip extra math */
+ else dist=x22-x12;
+
+ if (i==0) lastdist=dist;
+
+ /* if dist changes sign, and intersect point in edge's Bound Box*/
+ if ((lastdist*dist)<=0){
+ xdiff1=(x12-x11); /* Equation of line between last 2 points */
+ if (xdiff1){
+ m1=(y12-y11)/xdiff1;
+ b1= ((x12*y11)-(x11*y12))/xdiff1;
+ }
+ else{
+ m1=MAXSLOPE;
+ b1=x12;
+ }
+ x2max=MAX2(x21,x22)+0.001; /* prevent missed edges */
+ x2min=MIN2(x21,x22)-0.001; /* due to round off error */
+ y2max=MAX2(y21,y22)+0.001;
+ y2min=MIN2(y21,y22)-0.001;
+
+ /* Found an intersect, calc intersect point */
+ if (m1==m2){ /* co-incident lines */
+ /* cut at 50% of overlap area*/
+ x1max=MAX2(x11, x12);
+ x1min=MIN2(x11, x12);
+ xi= (MIN2(x2max,x1max)+MAX2(x2min,x1min))/2.0;
+
+ y1max=MAX2(y11, y12);
+ y1min=MIN2(y11, y12);
+ yi= (MIN2(y2max,y1max)+MAX2(y2min,y1min))/2.0;
+ }
+ else if (m2==MAXSLOPE){
+ xi=x22;
+ yi=m1*x22+b1;
+ }
+ else if (m1==MAXSLOPE){
+ xi=x12;
+ yi=m2*x12+b2;
+ }
+ else {
+ xi=(b1-b2)/(m2-m1);
+ yi=(b1*m2-m1*b2)/(m2-m1);
+ }
+
+ /* Intersect inside bounding box of edge?*/
+ if ((xi>=x2min)&&(xi<=x2max)&&(yi<=y2max)&&(yi>=y2min)){
+ if ((m2<=1.0)&&(m2>=-1.0)) perc = (xi-x21)/(x22-x21);
+ else perc=(yi-y21)/(y22-y21); /*lower slope more accurate*/
+ isect=32768.0*(perc+0.0000153);
+ break;
+ }
+ }
+ lastdist=dist;
+ }
+ return(isect);
+}
+
diff --git a/source/blender/src/ghostwinlay.c b/source/blender/src/ghostwinlay.c
index e4fa0429d28..ffe10f0a19b 100644
--- a/source/blender/src/ghostwinlay.c
+++ b/source/blender/src/ghostwinlay.c
@@ -71,12 +71,13 @@ static GHOST_TStandardCursor convert_cursor(int curs) {
default:
case CURSOR_STD: return GHOST_kStandardCursorDefault;
case CURSOR_VPAINT: return GHOST_kStandardCursorRightArrow;
- case CURSOR_FACESEL: return GHOST_kStandardCursorRightArrow;
+ case CURSOR_FACESEL: return GHOST_kStandardCursorRightArrow;
case CURSOR_WAIT: return GHOST_kStandardCursorWait;
case CURSOR_EDIT: return GHOST_kStandardCursorCrosshair;
case CURSOR_HELP: return GHOST_kStandardCursorHelp;
case CURSOR_X_MOVE: return GHOST_kStandardCursorLeftRight;
case CURSOR_Y_MOVE: return GHOST_kStandardCursorUpDown;
+ case CURSOR_PENCIL: return GHOST_kStandardCursorPencil;
}
}
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 3050fcbe57d..d24c8ce0e02 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -974,7 +974,10 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case KKEY:
if(G.obedit) {
- if(G.obedit->type==OB_SURF) printknots();
+ if (G.qual & LR_SHIFTKEY ){
+ if (G.obedit->type==OB_MESH) KnifeSubdivide();
+ }
+ else if(G.obedit->type==OB_SURF) printknots();
}
else {
if(G.qual & LR_SHIFTKEY) {
diff --git a/source/blender/src/view.c b/source/blender/src/view.c
index b1d0c367cec..8025d7663e3 100644
--- a/source/blender/src/view.c
+++ b/source/blender/src/view.c
@@ -225,6 +225,22 @@ void project_short_noclip(float *vec, short *adr)
}
}
+void project_float(float *vec, float *adr)
+{
+ float fx, fy, vec4[4];
+
+ adr[0]= 3200.0;
+ VECCOPY(vec4, vec);
+ vec4[3]= 1.0;
+
+ Mat4MulVec4fl(G.vd->persmat, vec4);
+
+ if( vec4[3]>0.1 ) {
+ adr[0]= (curarea->winx/2.0)+(curarea->winx/2.0)*vec4[0]/vec4[3];
+ adr[1]= (curarea->winy/2.0)+(curarea->winy/2.0)*vec4[1]/vec4[3];
+ }
+}
+
int boundbox_clip(float obmat[][4], BoundBox *bb)
{
/* return 1: draw */