Robert (DetectiveThorn) Wenzlaff's Knife subdivide tool. See previous
message on Bf-committers for description.
This commit is contained in:
parent
1bc0f43da0
commit
5c2005cf06
|
@ -155,7 +155,8 @@ typedef enum {
|
|||
GHOST_kStandardCursorBottomRightCorner,
|
||||
GHOST_kStandardCursorBottomLeftCorner,
|
||||
GHOST_kStandardCursorCustom,
|
||||
GHOST_kStandardCursorNumCursors
|
||||
GHOST_kStandardCursorNumCursors,
|
||||
GHOST_kStandardCursorPencil
|
||||
} GHOST_TStandardCursor;
|
||||
|
||||
|
||||
|
|
|
@ -506,27 +506,28 @@ void GHOST_WindowWin32::loadCursor(bool visible, GHOST_TStandardCursor cursor) c
|
|||
bool success = true;
|
||||
LPCSTR id;
|
||||
switch (cursor) {
|
||||
case GHOST_kStandardCursorDefault: id = IDC_ARROW;
|
||||
case GHOST_kStandardCursorRightArrow: id = IDC_ARROW; break;
|
||||
case GHOST_kStandardCursorLeftArrow: id = IDC_ARROW; break;
|
||||
case GHOST_kStandardCursorInfo: id = IDC_SIZEALL; break; // Four-pointed arrow pointing north, south, east, and west
|
||||
case GHOST_kStandardCursorDestroy: id = IDC_NO; break; // Slashed circle
|
||||
case GHOST_kStandardCursorHelp: id = IDC_HELP; break; // Arrow and question mark
|
||||
case GHOST_kStandardCursorCycle: id = IDC_NO; break; // Slashed circle
|
||||
case GHOST_kStandardCursorSpray: id = IDC_SIZEALL; break; // Four-pointed arrow pointing north, south, east, and west
|
||||
case GHOST_kStandardCursorWait: id = IDC_WAIT; break; // Hourglass
|
||||
case GHOST_kStandardCursorText: id = IDC_IBEAM; break; // I-beam
|
||||
case GHOST_kStandardCursorCrosshair: id = IDC_CROSS; break; // Crosshair
|
||||
case GHOST_kStandardCursorUpDown: id = IDC_SIZENS; break; // Double-pointed arrow pointing north and south
|
||||
case GHOST_kStandardCursorLeftRight: id = IDC_SIZEWE; break; // Double-pointed arrow pointing west and east
|
||||
case GHOST_kStandardCursorTopSide: id = IDC_UPARROW; break; // Vertical arrow
|
||||
case GHOST_kStandardCursorBottomSide: id = IDC_SIZENS; break;
|
||||
case GHOST_kStandardCursorLeftSide: id = IDC_SIZEWE; break;
|
||||
case GHOST_kStandardCursorTopLeftCorner: id = IDC_SIZENWSE; break;
|
||||
case GHOST_kStandardCursorTopRightCorner: id = IDC_SIZENESW; break;
|
||||
case GHOST_kStandardCursorDefault: id = IDC_ARROW; break;
|
||||
case GHOST_kStandardCursorRightArrow: id = IDC_ARROW; break;
|
||||
case GHOST_kStandardCursorLeftArrow: id = IDC_ARROW; break;
|
||||
case GHOST_kStandardCursorInfo: id = IDC_SIZEALL; break; // Four-pointed arrow pointing north, south, east, and west
|
||||
case GHOST_kStandardCursorDestroy: id = IDC_NO; break; // Slashed circle
|
||||
case GHOST_kStandardCursorHelp: id = IDC_HELP; break; // Arrow and question mark
|
||||
case GHOST_kStandardCursorCycle: id = IDC_NO; break; // Slashed circle
|
||||
case GHOST_kStandardCursorSpray: id = IDC_SIZEALL; break; // Four-pointed arrow pointing north, south, east, and west
|
||||
case GHOST_kStandardCursorWait: id = IDC_WAIT; break; // Hourglass
|
||||
case GHOST_kStandardCursorText: id = IDC_IBEAM; break; // I-beam
|
||||
case GHOST_kStandardCursorCrosshair: id = IDC_CROSS; break; // Crosshair
|
||||
case GHOST_kStandardCursorUpDown: id = IDC_SIZENS; break; // Double-pointed arrow pointing north and south
|
||||
case GHOST_kStandardCursorLeftRight: id = IDC_SIZEWE; break; // Double-pointed arrow pointing west and east
|
||||
case GHOST_kStandardCursorTopSide: id = IDC_UPARROW; break; // Vertical arrow
|
||||
case GHOST_kStandardCursorBottomSide: id = IDC_SIZENS; break;
|
||||
case GHOST_kStandardCursorLeftSide: id = IDC_SIZEWE; break;
|
||||
case GHOST_kStandardCursorTopLeftCorner: id = IDC_SIZENWSE; break;
|
||||
case GHOST_kStandardCursorTopRightCorner: id = IDC_SIZENESW; break;
|
||||
case GHOST_kStandardCursorBottomRightCorner: id = IDC_SIZENWSE; break;
|
||||
case GHOST_kStandardCursorBottomLeftCorner: id = IDC_SIZENESW; break;
|
||||
default:
|
||||
case GHOST_kStandardCursorBottomLeftCorner: id = IDC_SIZENESW; break;
|
||||
case GHOST_kStandardCursorPencil: id = IDC_CROSS; break;
|
||||
default:
|
||||
success = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -600,6 +600,7 @@ getStandardCursor(
|
|||
GtoX(GHOST_kStandardCursorTopRightCorner, XC_top_right_corner); break;
|
||||
GtoX(GHOST_kStandardCursorBottomRightCorner, XC_bottom_right_corner); break;
|
||||
GtoX(GHOST_kStandardCursorBottomLeftCorner, XC_bottom_left_corner); break;
|
||||
GtoX(GHOST_kStandardCursorPencil, XC_pencil); break;
|
||||
default:
|
||||
xcursor_id = 0;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -47,7 +47,8 @@ enum {
|
|||
CURSOR_Y_MOVE,
|
||||
CURSOR_HELP,
|
||||
CURSOR_STD,
|
||||
CURSOR_NONE
|
||||
CURSOR_NONE,
|
||||
CURSOR_PENCIL
|
||||
};
|
||||
|
||||
void set_cursor(int curs);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue